PageRenderTime 25ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

/include/Socket/Socket.hpp

https://github.com/Krozark/cpp-Socket
C++ Header | 306 lines | 136 code | 52 blank | 118 comment | 6 complexity | 0179e635becdc458ca07174827048b1b MD5 | raw file
Possible License(s): LGPL-3.0
  1. #ifndef NTW_SOCKET_HPP
  2. #define NTW_SOCKET_HPP
  3. #ifdef _WIN32 //_WIN64
  4. #include <winsock2.h>
  5. #define MSG_NOSIGNAL 0
  6. typedef int socklen_t;
  7. #elif __linux //|| __unix //or __APPLE__
  8. #include <sys/types.h>
  9. #include <sys/socket.h>
  10. #include <netinet/in.h>
  11. #include <arpa/inet.h>
  12. #include <unistd.h> /* close */
  13. #include <netdb.h> /* gethostbyname */
  14. #define INVALID_SOCKET -1
  15. #define SOCKET_ERROR -1
  16. #define closesocket(s) ::close(s)
  17. typedef int SOCKET;
  18. typedef struct sockaddr_in SOCKADDR_IN;
  19. typedef struct sockaddr SOCKADDR;
  20. typedef struct in_addr IN_ADDR;
  21. #else
  22. #error not defined for this platform
  23. #endif
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. #include <errno.h>
  27. #include <string>
  28. #include <exception>
  29. #include <iostream>
  30. namespace ntw {
  31. /**
  32. * \brief A class to manage exception
  33. */
  34. class SocketExeption: public std::exception
  35. {
  36. public:
  37. /**
  38. * \brief Constructor
  39. * \param error Message to display
  40. */
  41. SocketExeption(std::string error) : msg(error) {};
  42. ~SocketExeption() throw() {};
  43. virtual const char* what() const throw()
  44. {
  45. return msg.c_str();
  46. };
  47. private:
  48. std::string msg; ///< the message
  49. };
  50. class SocketSerialized;
  51. /**
  52. * \brief A class tha encapsulate C socket, and made it mor easy to use
  53. */
  54. class Socket
  55. {
  56. public:
  57. //static int max_id;
  58. /**
  59. * \brief Named Dommaine type. Others can be used
  60. */
  61. enum Domain {IP=AF_INET, LOCAL=AF_UNIX};
  62. /**
  63. * \brief named Type of socket. Others can be used
  64. */
  65. enum Type {TCP=SOCK_STREAM, UDP=SOCK_DGRAM};
  66. /**
  67. * \brief Named Down mode
  68. */
  69. enum Down {SEND=0,RECIVE=1,BOTH=2};
  70. /**
  71. * \brief Constructor
  72. * \param dommaine the dommaine for the socket
  73. * \param type the type of socket
  74. * \param protocole the protocal to use default is 0
  75. */
  76. Socket(Domain dommaine,Type type,int protocole=0);
  77. /**
  78. * \brief Destructor
  79. */
  80. virtual ~Socket();
  81. Socket& operator=(const Socket&) = delete;
  82. /**
  83. * \return get the id of the socket
  84. */
  85. SOCKET id()const{return sock;}
  86. /**
  87. * \brief connect the socket to the host
  88. * \param host host adresse (ip or adresse)
  89. * \param port the port to use
  90. */
  91. bool connect(const std::string& host,int port);
  92. /**
  93. * \brief connect the socket to the host
  94. * \param port the port to use
  95. */
  96. bool connect(int port);
  97. /**
  98. * \brief connect the socket to the host
  99. */
  100. bool connect();
  101. /**
  102. * \brief disconnect the socket
  103. */
  104. bool disconnect();
  105. /**
  106. * \brief Bind the socket
  107. */
  108. void bind();
  109. /**
  110. * \brief call the listen C function
  111. */
  112. void listen(const int max_connexion);
  113. /**
  114. * \brief Short cut function to call bind and listen
  115. * \param port the port to use
  116. * \param max_connexion the number of client
  117. * \param host the host to use. default is INADDR_ANY
  118. */
  119. void serverMode(int port,const int max_connexion,std::string host="");
  120. /**
  121. * \brief Creat a new soket and call accept(Socket&) on it
  122. * \return the new connextion etablish
  123. */
  124. Socket accept();
  125. /**
  126. * \brief accept a new connection
  127. * \param client the new client
  128. */
  129. void accept(Socket& client);
  130. /**
  131. * \brief shutdown the socket
  132. * \param mode is the mod to close
  133. */
  134. bool shutdown(Down mode=Down::BOTH);
  135. /**
  136. * \brief Send data
  137. * \param data the buffer to send
  138. * \param size the buffer size
  139. * \param flags the flags to use
  140. */
  141. template<typename T>
  142. inline int send(const T* data,const size_t size,const int flags=MSG_NOSIGNAL) const
  143. {
  144. int res;
  145. if(need_connect)
  146. {
  147. res = ::send(sock,(const char*)data,size,flags);
  148. }
  149. else
  150. {
  151. res = ::sendto(sock,(const char*)data,size,flags,(SOCKADDR*)(&sock_cfg),sizeof(sock_cfg));
  152. }
  153. if(res <0)
  154. {
  155. perror("Send()");
  156. throw SocketExeption("Sending message fail");
  157. }
  158. return res;
  159. }
  160. /**
  161. * \brief Send data
  162. * \param data the buffer to send
  163. * \param size the buffer size
  164. * \param flags the flags to use (use 0 by default)
  165. * \param other the host to send datas
  166. */
  167. template<typename T>
  168. inline int send(const T* data,const size_t size,const int flags,const Socket& other) const
  169. {
  170. int res;
  171. if((res = ::sendto(sock,(const char*)data,size,flags,(SOCKADDR*)(&other.sock_cfg),sizeof(other.sock_cfg))) == SOCKET_ERROR)
  172. {
  173. perror("Send()");
  174. throw SocketExeption("Sending message fail");
  175. }
  176. return res;
  177. }
  178. /**
  179. * \brief receive data and stor it to the buffer
  180. * \param buffer the buffer to store the data receive
  181. * \param size the size of data to receive
  182. * \param flags the flags to use
  183. */
  184. template<typename T>
  185. inline int receive(T* buffer,const size_t size,const int flags=0) const
  186. {
  187. int res;
  188. if(need_connect)
  189. {
  190. res = ::recv(sock,(char*)buffer,size,flags);
  191. }
  192. else
  193. {
  194. SOCKADDR_IN from = {0}; ///< configuration struct
  195. socklen_t from_size=sizeof(from);
  196. res = ::recvfrom(sock,(char*)buffer,size,flags,(SOCKADDR*)(&from),&from_size);
  197. }
  198. return res;
  199. };
  200. /**
  201. * \brief receive data and store it to the buffer
  202. * \param buffer the buffer to store the data receive
  203. * \param size the size of data to receive
  204. * \param flags the flags to use
  205. * \param other the other socket mesg from
  206. */
  207. template<typename T>
  208. inline int receive(T* buffer,const size_t size,const int flags,Socket& other) const
  209. {
  210. socklen_t slen=sizeof(other.sock_cfg);
  211. return ::recvfrom(sock,(char*)buffer,size,flags,(SOCKADDR*)(&other.sock_cfg),&slen);
  212. }
  213. /**
  214. * \return return the ip
  215. */
  216. std::string getIp()const;
  217. /**
  218. * \return the port use
  219. */
  220. unsigned int getPort() const;
  221. /**
  222. * \brief set sock option for broadcast
  223. */
  224. bool setBroadcast(bool enable=true);
  225. /**
  226. * \brief set sock option for reuse
  227. */
  228. bool setReusable(bool enable=true);
  229. /**
  230. * \brief initialise the context
  231. */
  232. static void init();
  233. /**
  234. * \brief close the context
  235. */
  236. static void close();
  237. protected:
  238. friend class SocketSerialized;
  239. Socket(bool need_connect);///< intern use only;
  240. /**
  241. * \brief close the socket proprely
  242. */
  243. SOCKET sock; ///< C socket type
  244. SOCKADDR_IN sock_cfg; ///< configuration struct
  245. const bool need_connect;
  246. const int proto;
  247. private:
  248. #if __WIN32
  249. static WSADATA WSAData;
  250. #endif
  251. void _close();
  252. };
  253. };
  254. #endif