Network.h 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. //
  2. // Created by Nathan Touroux on 29/06/2017.
  3. //
  4. #ifndef NETWORK_NETWORK_H
  5. #define NETWORK_NETWORK_H
  6. #ifdef WIN32
  7. #include <winsock2.h>
  8. typedef int socklen_t;
  9. #define errno WSAGetLastError()
  10. #else
  11. #include <netdb.h>
  12. #include <sys/types.h>
  13. #include <sys/socket.h>
  14. #include <netinet/in.h>
  15. #include <arpa/inet.h>
  16. #include <unistd.h>
  17. #define INVALID_SOCKET -1
  18. #define SOCKET_ERROR -1
  19. #define closesocket(s) close (s)
  20. typedef int SOCKET;
  21. typedef struct sockaddr_in SOCKADDR_IN;
  22. typedef struct sockaddr SOCKADDR;
  23. #endif // WIN32
  24. #include <iostream>
  25. #include <vector>
  26. #include <unordered_map>
  27. #include <thread>
  28. #include <atomic>
  29. #include <mutex>
  30. #include <cstdlib>
  31. #include <string.h>
  32. #define size_data unsigned long
  33. struct Sock
  34. {
  35. SOCKADDR_IN sin;
  36. SOCKET sock = SOCKET_ERROR;
  37. socklen_t recsize = sizeof(sin);
  38. std::string IP = "";
  39. std::string name = "";
  40. int port = 0;
  41. };
  42. //*********************************************** TCP DATA ***********************************************
  43. struct NetPacket{//should be created by NetData, contains length next to the data in "data", "size" is sizeof(size_data)+length of data
  44. void* data;
  45. size_data size;
  46. };
  47. class NetData{
  48. private:
  49. void* data;
  50. size_data size;
  51. void copy(void* data, size_data size);
  52. public:
  53. template<typename T, typename = typename std::enable_if<std::is_arithmetic<T>::value>::type> NetData(T data);
  54. NetData(std::string str);
  55. NetData(const char *str);
  56. NetData(void *data, size_data size, bool copyData = true);
  57. NetData(const NetData &copy);
  58. NetData& operator=(const NetData &copy);
  59. ~NetData();
  60. bool valid();
  61. template<typename T, typename = typename std::enable_if<std::is_arithmetic<T>::value>::type> operator T();
  62. operator std::string();
  63. void* getData();
  64. size_data getSize();
  65. NetPacket toPacket();//return a packet (the data inside should be freed)
  66. };
  67. template<typename T, typename> NetData::NetData(T data): data(nullptr), size(sizeof(T)) {
  68. copy(&data, size);
  69. }
  70. template<typename T, typename> NetData::operator T() {
  71. if(!valid()) return T();
  72. auto tmp = data;
  73. copy(data, size);
  74. return *static_cast<T*>(tmp);
  75. }
  76. //*********************************************** TCP CLIENT ***********************************************
  77. class TCPServer;
  78. class TCPClient{
  79. private:
  80. Sock sock;
  81. TCPServer *server;
  82. struct Data{
  83. void* data;
  84. size_data size;
  85. Data* next;
  86. };
  87. Data *first, *last;
  88. int nbData;
  89. std::thread *asyncThread;
  90. std::atomic_bool asynchronous;
  91. std::atomic_bool connected;
  92. std::mutex mutex;
  93. bool invalid();
  94. long unsafeSend(NetData data);
  95. NetData unsafeReceive();
  96. static void asyncReceive(TCPClient *client);
  97. void push(void* data, size_data size);
  98. NetData pop();
  99. public:
  100. TCPClient(bool asynchronous = true);
  101. TCPClient(const TCPClient &client);//just copy the asynchronous value
  102. ~TCPClient();
  103. bool accept(TCPServer *server, bool receiveName = false);//if receive name is true, the server must send a string
  104. // (message doesn't import) to confirm that the name is accepted or else disconnect the client
  105. bool connect(std::string IP, int port, std::string name = "");//if a client is already connected with this name the
  106. // connection will fail
  107. void disconnect(bool removeFromServer = true);
  108. bool isConnected();
  109. void enableAsynchronous();
  110. //void disableAsynchronous();
  111. bool asynchronousEnabled();
  112. //WARNING: can't send/receive raw packet when asynchronous
  113. long rawSend(void *data, size_data sizeByte);
  114. long rawReceive(void *data, size_data sizeByte);
  115. long send(NetData data);
  116. NetData receive();//receive a packet with size next to the data so knowing the size isn't important
  117. std::string getIP() const;
  118. std::string getName() const;
  119. int getPort() const;
  120. int getNbData() const;
  121. };
  122. //*********************************************** TCP SERVEUR ***********************************************
  123. class TCPServer{
  124. private:
  125. #ifdef WIN32
  126. WSADATA m_WSAData;
  127. #endif
  128. Sock hsock;
  129. std::vector<TCPClient> clients;
  130. std::unordered_map<std::string, TCPClient*> clientsByIP;
  131. std::unordered_map<std::string, TCPClient*> clientsByName;
  132. std::thread *thread;
  133. int port;
  134. int error;
  135. std::atomic<int> nbConnections;
  136. std::atomic<int> nbConnected;
  137. bool useName;
  138. bool hosting;
  139. bool autoReconnect;
  140. unsigned int maxConnectionTry;
  141. static void waitHost(TCPServer *data);
  142. bool invalid(int client);//return true if there is a problem, false if everything is fine
  143. TCPClient empty;
  144. public:
  145. explicit TCPServer(int port, unsigned int nbConnections, bool useName = false, bool asynchronous = true);
  146. ~TCPServer();
  147. bool host(bool waitConnections = false, bool autoReconnect = true, unsigned int maxConnectionTry = -1);
  148. bool acceptHost();//must not be called directly, it is used by host() method
  149. TCPClient& operator[](int index);
  150. TCPClient& operator[](std::string IP);
  151. TCPClient& operator()(std::string name);
  152. TCPClient& unavailable();//use this to compare against a client (ex: server[2] != server.unavailable())
  153. void eraseClient(TCPClient &client);
  154. std::vector<std::string> IPList();
  155. std::vector<std::string> namesList();
  156. Sock getHostSock() const;
  157. int getNbConnected() const;
  158. };
  159. //*********************************************** UDP ***********************************************
  160. class UDP{
  161. private:
  162. std::string IP;
  163. int port;
  164. Sock sock;
  165. sockaddr from;
  166. socklen_t fromaddrsize;
  167. public:
  168. UDP(std::string IP, int port);// use "" for IP to receive from any IP
  169. ~UDP();
  170. bool init();
  171. long rawSend(void *data, size_data sizeByte);
  172. long rawReceive(void *data, size_data sizeByte);
  173. long send(NetData data);
  174. NetData receive();//receive a packet with size next to the data so knowing the size isn't important
  175. int getPort();
  176. std::string getIP();
  177. //************************************ STATIC ************************************
  178. static long rawSendTo(std::string IP, int port, void *data, size_data sizeByte);
  179. static long sendTo(std::string IP, int port, NetData data);
  180. static long rawReceiveFrom(std::string IP, int port, void *data, size_data sizeByte);
  181. static long rawReceiveFrom(int port, void *data, size_data sizeByte);//TODO add possibility to know from wich ip it comes from
  182. static NetData receiveFrom(std::string IP, int port);
  183. static NetData receiveFrom(int port);
  184. };
  185. #endif //NETWORK_NETWORK_H