PageRenderTime 50ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 0ms

/gNET/gNET.cpp

https://gitlab.com/xKIVIx/My_Game
C++ | 260 lines | 246 code | 11 blank | 3 comment | 41 complexity | 7773c7aa7ebbfffd2d30690fe6763565 MD5 | raw file
  1. #define gNET_DLL
  2. #define LOG_ON
  3. #include "gNET.h"
  4. #include <loger\log_error.h>
  5. gNET::gNET(TYPE_NET type, char * server_name)
  6. {
  7. // init sock interface
  8. if (WSAStartup(MAKEWORD(2, 2), &wsa_data_)!=0)
  9. {
  10. LogSend(LOG_CRITICAL_ERROR, "gNET", "Can`t init socket API");
  11. return;
  12. }
  13. // init output socket
  14. output_sock_ = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  15. if (output_sock_ == INVALID_SOCKET)
  16. {
  17. LogSend(LOG_CRITICAL_ERROR, "gNET", "Can`t init output socket");
  18. WSACleanup();
  19. return;
  20. }
  21. // init input socket
  22. input_sock_ = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  23. if (output_sock_ == INVALID_SOCKET)
  24. {
  25. LogSend(LOG_CRITICAL_ERROR, "gNET", "Can`t init input socket");
  26. WSACleanup();
  27. return;
  28. }
  29. sucsses_init_ = 1;
  30. switch (type)
  31. {
  32. case SERVER:
  33. {
  34. InitServerState();
  35. break;
  36. }
  37. case CLIENT:
  38. {
  39. InitClientState(server_name);
  40. break;
  41. }
  42. default:
  43. {
  44. break;
  45. }
  46. }
  47. output_thread_ = std::thread(&gNET::SendMessegeThread, this);
  48. input_thread_ = std::thread(&gNET::GetMessegeThread, this);
  49. }
  50. gNET::~gNET()
  51. {
  52. Stop();
  53. lock_input_buffer_.lock();
  54. lock_output_buffer_.lock();
  55. shutdown(output_sock_, NULL);
  56. shutdown(input_sock_, NULL);
  57. output_thread_.detach();
  58. input_thread_.detach();
  59. lock_input_buffer_.unlock();
  60. lock_output_buffer_.unlock();
  61. closesocket(output_sock_);
  62. closesocket(input_sock_);
  63. WSACleanup();
  64. }
  65. void gNET::SendCommand(char com)
  66. {
  67. std::lock_guard <std::mutex> lock(lock_output_buffer_);
  68. size_output_buffer_++;
  69. char * tmp_buffer = new char[size_output_buffer_];
  70. if (output_buffer_ != NULL)
  71. {
  72. memcpy_s(tmp_buffer, size_output_buffer_, output_buffer_, size_output_buffer_ - 1);
  73. delete[] output_buffer_;
  74. }
  75. tmp_buffer[size_output_buffer_ - 1] = com;
  76. output_buffer_ = tmp_buffer;
  77. }
  78. bool gNET::GetCommand(char ** comands, unsigned int * count_com)
  79. {
  80. std::lock_guard <std::mutex> lock(lock_input_buffer_);
  81. *comands = input_buffer_;
  82. *count_com = size_input_buffer_;
  83. input_buffer_ = NULL;
  84. size_input_buffer_ = 0;
  85. return CheckStopState();
  86. }
  87. void gNET::InitClientState(char * server_name)
  88. {
  89. LogSend(LOG_INFO, "gNET", "Init client state");
  90. sockaddr_in adress_out, adress_in;
  91. hostent* host;
  92. char * ip;
  93. host = gethostbyname(server_name);
  94. ip = inet_ntoa(*(struct in_addr *)*host->h_addr_list);
  95. adress_out.sin_addr.S_un.S_addr = inet_addr(ip);
  96. adress_out.sin_family = AF_INET;
  97. adress_out.sin_port = htons(3300);
  98. adress_in = adress_out;
  99. adress_in.sin_port = htons(3301);
  100. if (connect(output_sock_, (SOCKADDR*)&adress_out, sizeof(adress_out)) == SOCKET_ERROR)
  101. {
  102. LogSend(LOG_CRITICAL_ERROR, "gNET", "Error connect output line");
  103. sucsses_init_ = 0;
  104. return;
  105. }
  106. if (connect(input_sock_, (SOCKADDR*)&adress_in, sizeof(adress_in)) == SOCKET_ERROR)
  107. {
  108. LogSend(LOG_CRITICAL_ERROR, "gNET", "Error connect input line");
  109. sucsses_init_ = 0;
  110. return;
  111. }
  112. }
  113. void gNET::InitServerState()
  114. {
  115. LogSend(LOG_INFO, "gNET", "Init server state");
  116. sockaddr_in adress_out, adress_in;
  117. hostent* host;
  118. char * ip;
  119. host = gethostbyname("localhost");
  120. ip = inet_ntoa(*(struct in_addr *)*host->h_addr_list);
  121. adress_out.sin_addr.S_un.S_addr = inet_addr(ip);
  122. adress_out.sin_family = AF_INET;
  123. adress_out.sin_port = htons(3301);
  124. adress_in = adress_out;
  125. adress_in.sin_port = htons(3300);
  126. if ((bind(output_sock_, (SOCKADDR*)&adress_out, sizeof(adress_out)) == SOCKET_ERROR)||
  127. (bind(input_sock_, (SOCKADDR*)&adress_in, sizeof(adress_in)) == SOCKET_ERROR))
  128. {
  129. LogSend(LOG_CRITICAL_ERROR, "gNET", "Error binding sockets");
  130. sucsses_init_ = 0;
  131. return;
  132. }
  133. if (listen(input_sock_, 1) == SOCKET_ERROR)
  134. {
  135. LogSend(LOG_CRITICAL_ERROR, "gNET", "Error listen input line");
  136. sucsses_init_ = 0;
  137. return;
  138. }
  139. SOCKET tmp_sock = input_sock_;
  140. input_sock_ = accept(input_sock_, NULL, NULL);
  141. closesocket(tmp_sock);
  142. if (input_sock_ == INVALID_SOCKET)
  143. {
  144. LogSend(LOG_CRITICAL_ERROR, "gNET", "Error input line");
  145. sucsses_init_ = 0;
  146. return;
  147. }
  148. if (listen(output_sock_, 1) == SOCKET_ERROR)
  149. {
  150. LogSend(LOG_CRITICAL_ERROR, "gNET", "Error listen output line");
  151. sucsses_init_ = 0;
  152. return;
  153. }
  154. tmp_sock = output_sock_;
  155. output_sock_ = accept(output_sock_, NULL, NULL);
  156. closesocket(tmp_sock);
  157. if (output_sock_ == INVALID_SOCKET)
  158. {
  159. LogSend(LOG_CRITICAL_ERROR, "gNET", "Error output line");
  160. sucsses_init_ = 0;
  161. return;
  162. }
  163. }
  164. void gNET::GetMessegeThread()
  165. {
  166. char * tmp_buffer = NULL, * tmp_input_buf = NULL;
  167. int count_com_sent = 0;
  168. while (!CheckStopState())
  169. {
  170. tmp_input_buf = new char[250];
  171. count_com_sent = recv(input_sock_, tmp_input_buf, 249, NULL);
  172. if (count_com_sent < 0)
  173. {
  174. LogSend(LOG_ERROR, "gNET", "Input error");
  175. return;
  176. }
  177. unsigned int new_size;
  178. std::lock_guard <std::mutex> lock(lock_input_buffer_);
  179. new_size = size_input_buffer_ + unsigned int(count_com_sent);
  180. tmp_buffer = new char[new_size];
  181. if (input_buffer_ != NULL)
  182. {
  183. memcpy_s(tmp_buffer, new_size, input_buffer_, size_input_buffer_);
  184. delete[] input_buffer_;
  185. }
  186. for (unsigned int i = 0; i < count_com_sent; i++)
  187. {
  188. tmp_buffer[size_input_buffer_ + i] = tmp_input_buf[i];
  189. }
  190. delete[] tmp_input_buf;
  191. size_input_buffer_ = new_size;
  192. input_buffer_ = tmp_buffer;
  193. }
  194. if (input_buffer_ != NULL)
  195. {
  196. size_input_buffer_ = 0;
  197. delete[] input_buffer_;
  198. }
  199. }
  200. void gNET::SendMessegeThread()
  201. {
  202. while (!CheckStopState())
  203. {
  204. std::lock_guard <std::mutex> lock (lock_output_buffer_);
  205. if (output_buffer_ != NULL)
  206. {
  207. int k = send(output_sock_, output_buffer_, size_output_buffer_, NULL);
  208. if (k < 0)
  209. {
  210. Stop();
  211. return;
  212. }
  213. unsigned int count_send = unsigned int(k);
  214. if (count_send != size_input_buffer_)
  215. {
  216. char * tmp_buffer = new char[size_output_buffer_ - count_send];
  217. for (unsigned int i = count_send; i < size_output_buffer_; i++)
  218. tmp_buffer[i - count_send] = output_buffer_[i];
  219. delete[]output_buffer_;
  220. output_buffer_ = tmp_buffer;
  221. size_output_buffer_ -= count_send;
  222. }
  223. else
  224. {
  225. if (output_buffer_ != NULL)
  226. {
  227. delete[] output_buffer_;
  228. output_buffer_ = NULL;
  229. }
  230. }
  231. }
  232. }
  233. if (output_buffer_ != NULL)
  234. {
  235. size_output_buffer_ = 0;
  236. delete[] output_buffer_;
  237. }
  238. }
  239. bool gNET::CheckStopState()
  240. {
  241. std::lock_guard <std::mutex> lock(lock_stop_state_);
  242. return stop_;
  243. }
  244. void gNET::Stop()
  245. {
  246. LogSend(LOG_INFO, "gNET", "Stop net");
  247. std::lock_guard <std::mutex> lock(lock_stop_state_);
  248. stop_ = 1;
  249. }