PageRenderTime 58ms CodeModel.GetById 30ms RepoModel.GetById 1ms app.codeStats 0ms

/src/Socket/Socket.cpp

https://github.com/Krozark/cpp-Socket
C++ | 208 lines | 159 code | 38 blank | 11 comment | 22 complexity | cb7227a99922e84507d39f34761b0ced MD5 | raw file
Possible License(s): LGPL-3.0
  1. #include <utility>
  2. #include <iostream>
  3. #include <Socket/Socket.hpp>
  4. #include <Socket/FuncWrapper.hpp>
  5. #include <string.h>
  6. namespace ntw {
  7. //int Socket::max_id = 0;
  8. #if __WIN32
  9. WSADATA Socket::WSAData;
  10. #endif
  11. Socket::Socket(Socket::Domain domain,Socket::Type type,int protocole) : sock(INVALID_SOCKET), need_connect(type == Socket::Type::TCP), proto(protocole)
  12. {
  13. //déclaration de la socket
  14. if((sock = ::socket(domain,type,proto)) == INVALID_SOCKET)
  15. {
  16. ::perror("socket()");
  17. throw SocketExeption("Invalid socket");
  18. }
  19. ::memset((char*)&sock_cfg,0,sizeof(sock_cfg)); // mise a 0
  20. sock_cfg.sin_family = domain;
  21. };
  22. Socket::Socket(bool need_conn) : sock(INVALID_SOCKET), need_connect(need_conn),proto(0)
  23. {
  24. }
  25. Socket::~Socket()
  26. {
  27. //shutdown();
  28. _close();
  29. };
  30. bool Socket::connect(const std::string& host,int port)
  31. {
  32. //sin_addr.s_addr = adresse IP
  33. sock_cfg.sin_addr.s_addr = inet_addr(host.c_str());
  34. //sin_port = port à utiliser
  35. sock_cfg.sin_port = htons(port);
  36. return connect();
  37. };
  38. bool Socket::connect(int port)
  39. {
  40. //sin_addr.s_addr = adresse IP
  41. sock_cfg.sin_addr.s_addr = htonl(INADDR_ANY);
  42. //sin_port = port à utiliser
  43. sock_cfg.sin_port = htons(port);
  44. return connect();
  45. }
  46. bool Socket::connect()
  47. {
  48. if(need_connect)
  49. {
  50. if(::connect(sock, (SOCKADDR*)&sock_cfg, sizeof(sockaddr)) != SOCKET_ERROR)
  51. {
  52. std::cerr<<"[Socket] <id:"<<sock<<">Connected to "<<inet_ntoa(sock_cfg.sin_addr)<<":"<<htons(sock_cfg.sin_port)<<std::endl;
  53. return true;
  54. }
  55. else
  56. {
  57. //std::cerr<<"[Socket] <id:"<<sock<<">Unable to connect"<<std::endl;
  58. return false;
  59. }
  60. }
  61. return true;
  62. }
  63. bool Socket::disconnect()
  64. {
  65. int domain;
  66. int type;
  67. socklen_t length = sizeof( int );
  68. bool res = true;
  69. domain = sock_cfg.sin_family;
  70. if(::getsockopt(sock, SOL_SOCKET, SO_TYPE, (char*)&type, &length )==0)
  71. {
  72. _close();
  73. if((sock = ::socket(domain,type,proto)) == INVALID_SOCKET)
  74. {
  75. ::perror("socket()");
  76. throw SocketExeption("Invalid socket");
  77. }
  78. ::memset((char*)&sock_cfg,0,sizeof(sock_cfg)); // mise a 0
  79. sock_cfg.sin_family = domain;
  80. }
  81. else
  82. res = false;
  83. return res;
  84. }
  85. void Socket::bind()
  86. {
  87. if(::bind(sock,(SOCKADDR*)&sock_cfg,sizeof(sock_cfg)) == SOCKET_ERROR)
  88. {
  89. perror("bind()");
  90. throw SocketExeption("Unable to bind soket");
  91. }
  92. }
  93. void Socket::listen(const int max_connexion)
  94. {
  95. if(::listen(sock,max_connexion) == SOCKET_ERROR)
  96. {
  97. perror("listen()");
  98. throw SocketExeption("Unable to listen");
  99. }
  100. }
  101. void Socket::serverMode(int port,const int max_connexion,std::string host)
  102. {
  103. //sin_addr.s_addr = adresse IP à utiliser
  104. //IP automatiquement chopée
  105. if(host.size() == 0)
  106. sock_cfg.sin_addr.s_addr = htonl(INADDR_ANY);
  107. else
  108. sock_cfg.sin_addr.s_addr= inet_addr(host.c_str());
  109. //sin_port = port à utiliser
  110. sock_cfg.sin_port = htons(port);
  111. bind();
  112. listen(max_connexion);
  113. };
  114. Socket Socket::accept()
  115. {
  116. Socket client(true);
  117. accept(client);
  118. return client;
  119. };
  120. void Socket::accept(Socket& client)
  121. {
  122. socklen_t size = sizeof(sockaddr_in);
  123. client.sock = ::accept(sock,(sockaddr*) &(client.sock_cfg), &size);
  124. if (client.sock == INVALID_SOCKET)
  125. {
  126. perror("accept()");
  127. throw SocketExeption("Invalid socket on accept");
  128. }
  129. std::cerr<<"[Socket] <id:"<<sock<<">New connexion accepted <id:"<<client.sock<<"> from "<<inet_ntoa(client.sock_cfg.sin_addr)<<":"<<htons(client.sock_cfg.sin_port)<<std::endl;
  130. };
  131. bool Socket::shutdown(Socket::Down mode)
  132. {
  133. return ::shutdown(sock,mode) != -1;
  134. };
  135. std::string Socket::getIp() const
  136. {
  137. return std::string(inet_ntoa(sock_cfg.sin_addr));
  138. }
  139. unsigned int Socket::getPort() const
  140. {
  141. return htons(sock_cfg.sin_port);
  142. }
  143. bool Socket::setBroadcast(bool enable)
  144. {
  145. int tmp = enable;
  146. return ::setsockopt(sock,SOL_SOCKET,SO_BROADCAST,(const char*)&tmp,sizeof(tmp)) == 0;
  147. }
  148. bool Socket::setReusable(bool enable)
  149. {
  150. int tmp = enable;
  151. return ::setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(const char*)&tmp,sizeof(int)) == 0;
  152. }
  153. void Socket::init()
  154. {
  155. #if __WIN32
  156. WSAStartup(MAKEWORD(2,0),&Socket::WSAData);
  157. #endif // __WIN32
  158. }
  159. void Socket::close()
  160. {
  161. #if __WIN32
  162. WSACleanup();
  163. #endif // __WIN32
  164. }
  165. void Socket::_close()
  166. {
  167. if(sock != INVALID_SOCKET)
  168. closesocket(sock);
  169. }
  170. };