Network.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599
  1. //
  2. // Created by Nathan Touroux on 29/06/2017.
  3. //
  4. #include "Network.h"
  5. //*********************************************** TCP DATA ***********************************************
  6. NetData::NetData(std::string str): data(nullptr), size(str.size()) {
  7. copy((void*)str.c_str(), size);
  8. }
  9. NetData::NetData(const char *str): data(nullptr), size(std::strlen(str)) {
  10. copy((void*)str, size);
  11. }
  12. NetData::NetData(void *data, size_data size, bool copyData) : data(data), size(size) {
  13. if(copyData) copy(data, size);
  14. }
  15. NetData::NetData(const NetData &toCopy): data(nullptr), size(toCopy.size){
  16. copy(toCopy.data, size);
  17. }
  18. NetData& NetData::operator=(const NetData &toCopy){
  19. size = toCopy.size;
  20. free(data);
  21. copy(toCopy.data, size);
  22. return *this;
  23. }
  24. NetData::~NetData(){
  25. if(data != nullptr) free(data);
  26. }
  27. void NetData::copy(void* data, size_data size){
  28. if(size == 0){
  29. this->data = nullptr;
  30. }else{
  31. this->data = malloc(size);
  32. memcpy(this->data, data, size);
  33. }
  34. }
  35. bool NetData::valid(){
  36. return data != nullptr && size != 0;
  37. }
  38. NetData::operator std::string() {
  39. if(!valid()) return "";
  40. char arr[size+1];
  41. memcpy(arr, data, size);
  42. arr[size] = '\0';
  43. return std::string(arr);
  44. }
  45. void* NetData::getData(){
  46. auto tmp = data;
  47. copy(data, size);
  48. return tmp;
  49. }
  50. size_data NetData::getSize(){
  51. return size;
  52. }
  53. NetPacket NetData::toPacket(){
  54. if(!valid()) return {nullptr, 0};
  55. auto sizePacket = sizeof(size_data)+size;
  56. auto packet = (char*)malloc(sizePacket);
  57. memcpy(packet, &size, sizeof(size_data));
  58. memcpy(packet+sizeof(size_data), data, size);
  59. return {packet, sizePacket};
  60. }
  61. //**************************************************** TCP Client ****************************************************
  62. TCPClient::TCPClient(bool asynchronous): sock(), server(nullptr), first(nullptr), nbData(0), asyncThread(nullptr), asynchronous(asynchronous), connected(false) {
  63. }
  64. TCPClient::TCPClient(const TCPClient &client): sock(), server(nullptr), first(nullptr), nbData(0), asyncThread(nullptr), asynchronous(client.asynchronous.load()), connected(false){
  65. }
  66. TCPClient::~TCPClient(){
  67. disconnect();
  68. }
  69. bool TCPClient::invalid(){
  70. return !connected;
  71. }
  72. bool TCPClient::accept(TCPServer *server, bool receiveName){
  73. if(connected) return false;//if already connected stop there
  74. sock.sock = ::accept(server->getHostSock().sock, (SOCKADDR*)&sock.sin, &sock.recsize);
  75. if(sock.sock == INVALID_SOCKET) return false;
  76. sock.IP = inet_ntoa(sock.sin.sin_addr);
  77. if(receiveName){
  78. std::string name = unsafeReceive();
  79. sock.name = name;
  80. }
  81. this->server = server;
  82. connected = true;
  83. if(asynchronous) asyncThread = new std::thread(asyncReceive, this);
  84. return sock.sock != SOCKET_ERROR;
  85. }
  86. bool TCPClient::connect(std::string IP, int port, std::string name){
  87. if(connected) return false;//if already connected stop there
  88. sock.IP = IP;
  89. sock.port = port;
  90. sock.sock = socket(AF_INET,SOCK_STREAM, 0);
  91. if(sock.sock == INVALID_SOCKET) return false;
  92. sock.sin.sin_addr.s_addr = inet_addr(IP.c_str());
  93. sock.sin.sin_family = AF_INET;
  94. sock.sin.sin_port = htons(port);
  95. if(::connect(sock.sock, (SOCKADDR*)&sock.sin, sock.recsize) == SOCKET_ERROR) return false;
  96. if(!name.empty()){
  97. unsafeSend(name);
  98. unsafeReceive();//to confirm if name is accepted
  99. }
  100. connected = true;
  101. if(asynchronous) asyncThread = new std::thread(asyncReceive, this);
  102. return sock.sock != SOCKET_ERROR;
  103. }
  104. void TCPClient::disconnect(bool removeFromServer) {
  105. if(!connected) return; //nothing to do
  106. if(server && removeFromServer){
  107. server->eraseClient(*this);
  108. }else{
  109. connected = false;
  110. closesocket(sock.sock);
  111. sock.sock = SOCKET_ERROR;
  112. sock.name = "";
  113. sock.IP = "";
  114. //std::lock_guard<std::mutex> guard(mutex);
  115. if(asyncThread){
  116. std::cout << "1" << std::endl;//TODO remove
  117. if(asyncThread->joinable())
  118. asyncThread->detach();//TODO sometimes too slow
  119. delete asyncThread;
  120. asyncThread = nullptr;
  121. }
  122. }
  123. }
  124. bool TCPClient::isConnected(){
  125. return connected;
  126. }
  127. void TCPClient::enableAsynchronous(){
  128. if(asynchronous) return;//if already asynchronous, nothing to do
  129. asynchronous = true;
  130. if(connected) asyncThread = new std::thread(asyncReceive, this);
  131. }
  132. bool TCPClient::asynchronousEnabled() {
  133. return asynchronous;
  134. }
  135. void TCPClient::asyncReceive(TCPClient *client) {
  136. while(client->isConnected() && client->asynchronousEnabled()){
  137. auto data = client->unsafeReceive();
  138. if(data.valid())
  139. client->push(data.getData(), data.getSize());
  140. }
  141. }
  142. void TCPClient::push(void* data, size_data size){
  143. std::lock_guard<std::mutex> guard(mutex);
  144. Data *newdata = new Data{data, size, nullptr};
  145. if(first == nullptr){
  146. first = newdata;
  147. }else{
  148. last->next = newdata;
  149. }
  150. last = newdata;
  151. nbData++;
  152. }
  153. NetData TCPClient::pop(){
  154. std::lock_guard<std::mutex> guard(mutex);
  155. if(first == nullptr) return NetData(nullptr, 0);
  156. Data *data = first;
  157. first = first->next;
  158. NetData netdata(data->data, data->size, false);
  159. delete data;
  160. return netdata;
  161. }
  162. long TCPClient::unsafeSend(NetData data){
  163. auto packet = data.toPacket();
  164. long size = ::send(sock.sock, packet.data, packet.size, 0);
  165. free(packet.data);
  166. if(size == 0) if(errno == ECONNRESET) disconnect();//when sending check ECONNRESET
  167. return size;
  168. }
  169. NetData TCPClient::unsafeReceive(){
  170. size_data sizeByte;
  171. long size = ::recv(sock.sock, &sizeByte, sizeof(size_data), 0);
  172. if(size == 0) {
  173. disconnect();
  174. return NetData(nullptr, 0);
  175. }//when receiving just check for size == 0
  176. if(sizeByte == 0) return NetData(nullptr, 0);//check that the length of data is not 0
  177. void* data = malloc(sizeByte);
  178. size = ::recv(sock.sock, data, sizeByte, 0);
  179. if(size == 0) {
  180. disconnect();
  181. free(data);
  182. return NetData(nullptr, 0);
  183. }
  184. return NetData(data, sizeByte, false);//dont copy the data just the address so it will be freed automatically after
  185. }
  186. long TCPClient::rawSend(void *data, size_data sizeByte) {
  187. if(invalid() || asynchronous) return SOCKET_ERROR;//cant send raw packet when asynchronous
  188. long size = ::send(sock.sock, data, sizeByte, 0);
  189. if(size == 0) if(errno == ECONNRESET) disconnect();//when sending check ECONNRESET
  190. return size;
  191. }
  192. long TCPClient::rawReceive(void *data, size_data sizeByte) {
  193. if(invalid() || asynchronous) return SOCKET_ERROR;//cant receive raw packet when asynchronous
  194. long size = ::recv(sock.sock, data, sizeByte, 0);
  195. if(size == 0) disconnect();//when receiving just check for size == 0
  196. return size;
  197. }
  198. long TCPClient::send(NetData data){
  199. if(invalid()) return SOCKET_ERROR;
  200. return unsafeSend(data);
  201. }
  202. NetData TCPClient::receive(){
  203. if(invalid()) return NetData(nullptr, 0);
  204. if(asynchronous || nbData > 0)//if not asynchronous but data where stored asynchronously before, return these data
  205. // before using blocking receive
  206. return pop();
  207. else
  208. return unsafeReceive();
  209. }
  210. std::string TCPClient::getIP() const{
  211. return sock.IP;
  212. }
  213. std::string TCPClient::getName() const{
  214. return sock.name;
  215. }
  216. int TCPClient::getPort() const{
  217. return sock.port;
  218. }
  219. int TCPClient::getNbData() const{
  220. return nbData;
  221. }
  222. //**************************************************** TCP Serveur ****************************************************
  223. TCPServer::TCPServer(int port, unsigned int nbConnections, bool useName, bool asynchronous):
  224. clients(nbConnections, asynchronous), thread(nullptr), port(port), error(0), nbConnections(nbConnections),
  225. nbConnected(0), useName(useName), hosting(true), autoReconnect(false), maxConnectionTry(0){
  226. #ifdef WIN32
  227. error = WSAStartup(MAKEWORD(2,2), &m_WSAData);
  228. #else
  229. error = 0;
  230. #endif // WIN32
  231. }
  232. TCPServer::~TCPServer(){
  233. clients.clear();
  234. closesocket(hsock.sock);
  235. if(thread){
  236. hosting = false;
  237. thread->join();
  238. delete thread;
  239. thread = nullptr;
  240. }
  241. #ifdef WIN32
  242. WSACleanup();
  243. #endif // WIN32
  244. }
  245. bool TCPServer::host(bool waitConnections, bool autoReconnect, unsigned int maxConnectionTry) {
  246. if(error) return false;
  247. hsock.sock = socket(AF_INET,SOCK_STREAM, 0);
  248. if(hsock.sock == INVALID_SOCKET) return false;
  249. hsock.sin.sin_addr.s_addr = htonl(INADDR_ANY);
  250. hsock.sin.sin_family = AF_INET;
  251. hsock.sin.sin_port = htons(port);
  252. if(bind(hsock.sock, (SOCKADDR*)&hsock.sin, sizeof(hsock.sin)) == SOCKET_ERROR) return false;
  253. if(listen(hsock.sock, 1) == SOCKET_ERROR) return false;
  254. this->autoReconnect = autoReconnect;
  255. this->maxConnectionTry = maxConnectionTry;
  256. if(waitConnections){
  257. return acceptHost();
  258. }else{
  259. thread = new std::thread(waitHost, this);
  260. }
  261. return true;
  262. }
  263. bool TCPServer::acceptHost(){
  264. int connectionTry = 0;
  265. for(int i = 0;(i<nbConnections || autoReconnect) && hosting;i++){
  266. if(i == nbConnections) i = 0;//in case of autoReconnect
  267. if(clients[i].isConnected()) continue;
  268. if(!clients[i].accept(this, useName)){
  269. connectionTry++;
  270. if(connectionTry <= maxConnectionTry)
  271. return false;
  272. i--;
  273. continue;
  274. }
  275. connectionTry = 0;//connection made so reset connectionTry to 0
  276. std::string name = clients[i].getName();
  277. if(!name.empty()){
  278. auto client = clientsByName.find(name);
  279. if(client != clientsByName.end()){//if already exist disconnect
  280. if(client->second->isConnected() || !autoReconnect){//if !autoReconnect a client can't connect again
  281. clients[i].disconnect(false);
  282. i--;
  283. continue;
  284. }else{//else send acceptation message
  285. clients[i].send("accepted");
  286. }
  287. } else{//else send acceptation message
  288. clients[i].send("accepted");
  289. }
  290. clientsByName[name] = &clients[i];
  291. }
  292. clientsByIP[clients[i].getIP()] = &clients[i];
  293. nbConnected++;
  294. }
  295. return true;
  296. }
  297. void TCPServer::waitHost(TCPServer *tcp){
  298. tcp->acceptHost();
  299. }
  300. TCPClient& TCPServer::operator[](int index){
  301. if(invalid(index)) return empty;
  302. return clients[index];
  303. }
  304. TCPClient& TCPServer::operator[](std::string IP){
  305. if(clientsByIP.find(IP) == clientsByIP.end()) return empty;
  306. return *clientsByIP[IP];
  307. }
  308. TCPClient& TCPServer::operator()(std::string name){
  309. if(clientsByName.find(name) == clientsByName.end()) return empty;
  310. return *clientsByName[name];
  311. }
  312. TCPClient& TCPServer::unavailable(){
  313. return empty;
  314. }
  315. bool TCPServer::invalid(int client){
  316. if(client >= 0 && client < clients.size()) return !clients[client].isConnected();
  317. return true;
  318. }
  319. void TCPServer::eraseClient(TCPClient &client){
  320. if(client.isConnected()){
  321. auto IP = client.getIP();
  322. auto name = client.getName();
  323. client.disconnect(false);
  324. nbConnected--;
  325. if(!IP.empty())
  326. clientsByIP.erase(IP);
  327. if(!name.empty())
  328. clientsByName.erase(name);
  329. }
  330. }
  331. std::vector<std::string> TCPServer::IPList(){
  332. std::vector<std::string> IPs;
  333. for(auto const &elt : clientsByIP)
  334. IPs.push_back(elt.first);
  335. return IPs;
  336. }
  337. std::vector<std::string> TCPServer::namesList(){
  338. std::vector<std::string> names;
  339. for(auto const &elt : clientsByName)
  340. names.push_back(elt.first);
  341. return names;
  342. }
  343. Sock TCPServer::getHostSock() const{
  344. return hsock;
  345. }
  346. int TCPServer::getNbConnected() const{
  347. return nbConnected;
  348. }
  349. //**************************************************** UDP ****************************************************
  350. UDP::UDP(std::string IP, int port): IP(IP), port(port), sock(), from({0}), fromaddrsize(sizeof(from)){
  351. }
  352. UDP::~UDP(){
  353. closesocket(sock.sock);
  354. }
  355. bool UDP::init(){
  356. sock.sock = socket(PF_INET, SOCK_DGRAM, 0);
  357. if(sock.sock == INVALID_SOCKET) return false;
  358. sock.sin = { 0 };
  359. sock.recsize = sizeof sock.sin;
  360. if(IP == "")
  361. sock.sin.sin_addr.s_addr = htonl(INADDR_ANY);
  362. else
  363. sock.sin.sin_addr.s_addr = inet_addr(IP.c_str());
  364. sock.sin.sin_port = htons(port);
  365. sock.sin.sin_family = AF_INET;
  366. if(bind(sock.sock, (SOCKADDR *)&sock.sin, sock.recsize) == SOCKET_ERROR) return false;
  367. return true;
  368. }
  369. long UDP::send(NetData data){
  370. auto packet = data.toPacket();
  371. long size = sendto(sock.sock, packet.data, packet.size, 0, (SOCKADDR *)&sock.sin, sock.recsize);
  372. free(packet.data);
  373. return size;
  374. }
  375. NetData UDP::receive(){
  376. size_data sizeByte;
  377. long size = recvfrom(sock.sock, &sizeByte, sizeof(size_data), 0, &from, &fromaddrsize);
  378. if(size == 0 || sizeByte == 0) {
  379. return NetData(nullptr, 0);
  380. }//when receiving just check for size == 0
  381. void* data = malloc(sizeByte);
  382. size = recvfrom(sock.sock, data, sizeByte, 0, &from, &fromaddrsize);
  383. if(size == 0) {
  384. free(data);
  385. return NetData(nullptr, 0);
  386. }
  387. return NetData(data, sizeByte, false);//dont copy the data just the address so it will be freed automatically after
  388. }
  389. long UDP::rawSend(void *data, size_data sizeByte) {
  390. return sendto(sock.sock, data, sizeByte, 0, (SOCKADDR *)&sock.sin, sock.recsize);
  391. }
  392. long UDP::rawReceive(void *data, size_data sizeByte) {
  393. return recvfrom(sock.sock, data, sizeByte, 0, &from, &fromaddrsize);
  394. }
  395. int UDP::getPort(){
  396. return port;
  397. }
  398. std::string UDP::getIP(){
  399. if(IP != "")
  400. return IP;
  401. else{
  402. char host[NI_MAXHOST];
  403. if (getnameinfo((sockaddr*)&from, fromaddrsize, host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST) != 0) {
  404. return "";
  405. } else {
  406. return std::string(host);
  407. }
  408. }
  409. }
  410. //************************************ STATIC ************************************
  411. long UDP::rawSendTo(std::string IP, int port, void *data, size_data sizeByte){
  412. SOCKET sock = socket(PF_INET, SOCK_DGRAM, 0);
  413. if(sock == INVALID_SOCKET) return false;
  414. SOCKADDR_IN to = { 0 };
  415. socklen_t tosize = sizeof to;
  416. to.sin_addr.s_addr = inet_addr(IP.c_str());
  417. to.sin_port = htons(port);
  418. to.sin_family = AF_INET;
  419. long size = sendto(sock, data, sizeByte, 0, (SOCKADDR *)&to, tosize);
  420. closesocket(sock);
  421. return size;
  422. }
  423. long UDP::sendTo(std::string IP, int port, NetData data){
  424. SOCKET sock = socket(PF_INET, SOCK_DGRAM, 0);
  425. if(sock == INVALID_SOCKET) return false;
  426. SOCKADDR_IN to = { 0 };
  427. socklen_t tosize = sizeof to;
  428. to.sin_addr.s_addr = inet_addr(IP.c_str());
  429. to.sin_port = htons(port);
  430. to.sin_family = AF_INET;
  431. auto packet = data.toPacket();
  432. long size = sendto(sock, packet.data, packet.size, 0, (SOCKADDR *)&to, tosize);
  433. free(packet.data);
  434. closesocket(sock);
  435. return size;
  436. }
  437. long UDP::rawReceiveFrom(std::string IP, int port, void *data, size_data sizeByte){
  438. SOCKET sock = socket(PF_INET, SOCK_DGRAM, 0);
  439. if(sock == INVALID_SOCKET) return false;
  440. SOCKADDR_IN to = { 0 };
  441. socklen_t tosize = sizeof to;
  442. if(IP.empty())
  443. to.sin_addr.s_addr = htonl(INADDR_ANY);
  444. else
  445. to.sin_addr.s_addr = inet_addr(IP.c_str());
  446. to.sin_port = htons(port);
  447. to.sin_family = AF_INET;
  448. if(bind(sock, (SOCKADDR *)&to, tosize) == SOCKET_ERROR) return false;
  449. sockaddr from = { 0 };
  450. socklen_t addrsize = sizeof from;
  451. long size = recvfrom(sock, data, sizeByte, 0, &from, &addrsize);
  452. closesocket(sock);
  453. return size;
  454. }
  455. long UDP::rawReceiveFrom(int port, void *data, size_data sizeByte){
  456. return rawReceiveFrom("", port, data, sizeByte);
  457. }//TODO add possibility to know from wich ip it comes from
  458. NetData UDP::receiveFrom(std::string IP, int port){
  459. SOCKET sock = socket(PF_INET, SOCK_DGRAM, 0);
  460. if(sock == INVALID_SOCKET) return NetData(nullptr, 0);
  461. SOCKADDR_IN to = { 0 };
  462. socklen_t tosize = sizeof to;
  463. if(IP.empty())
  464. to.sin_addr.s_addr = htonl(INADDR_ANY);
  465. else
  466. to.sin_addr.s_addr = inet_addr(IP.c_str());
  467. to.sin_port = htons(port);
  468. to.sin_family = AF_INET;
  469. if(bind(sock, (SOCKADDR *)&to, tosize) == SOCKET_ERROR) return NetData(nullptr, 0);
  470. sockaddr from = { 0 };
  471. socklen_t addrsize = sizeof from;
  472. size_data sizeByte;
  473. long size = recvfrom(sock, &sizeByte, sizeof(size_data), 0, &from, &addrsize);
  474. if(size == 0 || sizeByte == 0) {
  475. return NetData(nullptr, 0);
  476. }//when receiving just check for size == 0
  477. void* data = malloc(sizeByte);
  478. size = recvfrom(sock, data, sizeByte, 0, &from, &addrsize);
  479. if(size == 0) {
  480. free(data);
  481. return NetData(nullptr, 0);
  482. }
  483. return NetData(data, sizeByte, false);//dont copy the data just the address so it will be freed automatically after
  484. }
  485. NetData UDP::receiveFrom(int port){
  486. return receiveFrom("", port);//dont copy the data just the address so it will be freed automatically after
  487. }