1 /* 2 * @file Socket.h 3 * @brief Abstract class to perform API global operations 4 * 5 * @author Mohamed Amine Mzoughi <mohamed-amine.mzoughi@laposte.net> 6 * @date 2017-02-10 7 */ 8 9 #ifndef INCLUDE_ASOCKET_H_ 10 #define INCLUDE_ASOCKET_H_ 11 12 #if defined (_WIN32) && !defined (WINDOWS) 13 #define WINDOWS 14 #endif 15 16 #include <cstdio> // snprintf 17 #include <exception> 18 #include <functional> 19 #include <memory> 20 #include <stdarg.h> // va_start, etc. 21 #include <stdexcept> 22 23 #ifdef WINDOWS 24 #include <winsock2.h> 25 #include <ws2tcpip.h> 26 27 // Need to link with Ws2_32.lib 28 #pragma comment(lib,"WS2_32.lib") 29 30 #else 31 #include <arpa/inet.h> 32 #include <errno.h> 33 #include <netinet/in.h> 34 #include <netdb.h> 35 #include <stdio.h> 36 #include <stdlib.h> 37 #include <string.h> 38 #include <string.h> 39 #include <sys/types.h> 40 #include <sys/socket.h> 41 #include <unistd.h> 42 #endif 43 44 #include <limits> 45 #define ACCEPT_WAIT_INF_DELAY std::numeric_limits<size_t>::max() 46 47 class ASocket 48 { 49 public: 50 // Public definitions 51 //typedef std::function<int(void*, double, double, double, double)> ProgressFnCallback; 52 typedef std::function<void(const std::string&)> LogFnCallback; 53 54 // socket file descriptor id 55 #ifdef WINDOWS 56 typedef SOCKET Socket; 57 #else 58 typedef int Socket; 59 #define INVALID_SOCKET -1 60 #endif 61 62 enum SettingsFlag 63 { 64 NO_FLAGS = 0x00, 65 ENABLE_LOG = 0x01, 66 ALL_FLAGS = 0xFF 67 }; 68 69 /* Please provide your logger thread-safe routine, otherwise, you can turn off 70 * error log messages printing by not using the flag ALL_FLAGS or ENABLE_LOG */ 71 explicit ASocket(const LogFnCallback& oLogger, 72 const SettingsFlag eSettings = ALL_FLAGS); 73 virtual ~ASocket() = 0; 74 75 static int SelectSockets(const Socket* pSocketsToSelect, const size_t count, 76 const size_t msec, size_t& selectedIndex); 77 78 static int SelectSocket(const Socket sd, const size_t msec); 79 80 static struct timeval TimevalFromMsec(unsigned int time_msec); 81 82 // String Helpers 83 static std::string StringFormat(const std::string strFormat, ...); 84 85 protected: 86 // Log printer callback 87 /*mutable*/const LogFnCallback m_oLog; 88 89 SettingsFlag m_eSettingsFlags; 90 91 #ifdef WINDOWS 92 static WSADATA s_wsaData; 93 #endif 94 95 private: 96 friend class SocketGlobalInitializer; 97 class SocketGlobalInitializer { 98 public: 99 static SocketGlobalInitializer& instance(); 100 101 SocketGlobalInitializer(SocketGlobalInitializer const&) = delete; 102 SocketGlobalInitializer(SocketGlobalInitializer&&) = delete; 103 104 SocketGlobalInitializer& operator=(SocketGlobalInitializer const&) = delete; 105 SocketGlobalInitializer& operator=(SocketGlobalInitializer&&) = delete; 106 107 ~SocketGlobalInitializer(); 108 109 private: 110 SocketGlobalInitializer(); 111 }; 112 SocketGlobalInitializer& m_globalInitializer; 113 }; 114 115 class EResolveError : public std::logic_error 116 { 117 public: EResolveError(const std::string & strMsg)118 explicit EResolveError(const std::string &strMsg) : std::logic_error(strMsg) {} 119 }; 120 121 #endif 122