TCPSocket.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476
  1. #include "stdafx.h"
  2. #include "TCPSocket.h"
  3. #include <iostream>
  4. #include <algorithm>
  5. #include <Ws2tcpip.h>
  6. #include "log4z.h"
  7. #include "LogInit.h"
  8. #include <process.h>
  9. LogInit _loginti;
  10. WinSocketSystem _winsocket_init;
  11. TCPServer::TCPServer()
  12. {
  13. m_pNotify = NULL;
  14. sockSrv = INVALID_SOCKET;
  15. sockCli = INVALID_SOCKET;
  16. }
  17. TCPServer::~TCPServer()
  18. {
  19. Stop();
  20. }
  21. int TCPServer::InitNet(const char*ip, int port, INetNotify*pNotify)
  22. {
  23. m_pNotify = pNotify;
  24. SOCKADDR_IN addrSrv;
  25. addrSrv.sin_family = AF_INET;
  26. addrSrv.sin_addr.s_addr = htonl(INADDR_ANY);//Auto IP, byte sequence change
  27. addrSrv.sin_port = htons(port);
  28. sockSrv = socket(AF_INET, SOCK_STREAM, 0);
  29. if (sockSrv == INVALID_SOCKET){
  30. LOGFMTE("create socket error errorno=%d", WSAGetLastError());
  31. return -2;
  32. }
  33. // 绑定
  34. int err = bind(sockSrv, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));
  35. if (err != 0){
  36. LOGFMTE("bind error errorno=%d", WSAGetLastError());
  37. return -3;
  38. }
  39. // 监听
  40. err = listen(sockSrv, 5);
  41. if (err != 0){
  42. LOGFMTE("listen error errorno=%d", WSAGetLastError());
  43. return -4;
  44. }
  45. // 启动监听线程
  46. _listen_thread = (HANDLE)::_beginthreadex(NULL, 0, &TCPServer::ListenThread, this, 0, NULL);
  47. LOGI("服务端启动监听成功");
  48. return 0;
  49. }
  50. int TCPServer::SendData(const char*data)
  51. {
  52. if (sockCli == INVALID_SOCKET){
  53. return -1;// 没有链接
  54. }
  55. char header[16] = { 0 };
  56. int data_size = strlen(data);
  57. std::string str_data = data;
  58. sprintf_s(header, "%12d", data_size);
  59. int nLen = 0;
  60. AutoLock _lck(m_tx_send);
  61. do {
  62. int send_tmp_ = send(sockCli, header + nLen, 12 - nLen, 0);
  63. if (send_tmp_ == SOCKET_ERROR){
  64. closesocket(sockCli);
  65. sockCli = INVALID_SOCKET;
  66. return -2;
  67. }
  68. else{
  69. nLen += send_tmp_;
  70. }
  71. } while (nLen < 12);
  72. nLen = 0;
  73. do {
  74. int send_tmp_ = send(sockCli, data + nLen, data_size - nLen, 0);
  75. if (send_tmp_ == SOCKET_ERROR){
  76. int last_error = WSAGetLastError();
  77. if (last_error == WSAEWOULDBLOCK){
  78. continue;
  79. }
  80. else{
  81. closesocket(sockCli);
  82. sockCli = INVALID_SOCKET;
  83. return -2;
  84. }
  85. }
  86. else{
  87. nLen += send_tmp_;
  88. }
  89. } while (nLen < data_size);
  90. return 0;
  91. }
  92. unsigned TCPServer::ListenThread(void *param)
  93. {
  94. TCPServer*pThis = static_cast<TCPServer*>(param);
  95. LOGI("启动监听线程");
  96. SOCKADDR_IN addrClt;
  97. int len = sizeof(SOCKADDR);
  98. while (!::InterlockedExchange((PLONG)&pThis->m_bexit, FALSE) && pThis->sockSrv != INVALID_SOCKET){
  99. SOCKET sockCon = accept(pThis->sockSrv, (SOCKADDR*)&addrClt, &len);
  100. if (sockCon == INVALID_SOCKET){
  101. continue;
  102. }
  103. else{
  104. if (pThis->sockCli != sockCon){
  105. if (pThis->sockCli != INVALID_SOCKET){
  106. closesocket(pThis->sockCli); pThis->sockCli = INVALID_SOCKET;
  107. if (pThis->m_pNotify)
  108. pThis->m_pNotify->OnNetNotify("{\"cmd\":\"socket_switch\"}");
  109. }
  110. // 新的链接
  111. pThis->sockCli = sockCon;
  112. if (pThis->m_pNotify)
  113. pThis->m_pNotify->OnNetNotify("{\"cmd\":\"new_connect\"}");
  114. }
  115. ::InterlockedExchange((PLONG)&pThis->m_bexit, TRUE);
  116. ::WaitForSingleObject(pThis->_recv_thread, INFINITE);
  117. ::InterlockedExchange((PLONG)&pThis->m_bexit, FALSE);
  118. // 启动接受线程
  119. pThis->_recv_thread = (HANDLE)::_beginthreadex(NULL, 0, &TCPServer::RecvThread, param, 0, NULL);
  120. }
  121. }
  122. LOGI("退出监听线程");
  123. return 0;
  124. }
  125. unsigned TCPServer::RecvThread(void *param)
  126. {
  127. TCPServer*pThis = static_cast<TCPServer*>(param);
  128. while (!::InterlockedExchange((PLONG)&pThis->m_bexit, FALSE) && pThis->sockSrv != INVALID_SOCKET){
  129. if (pThis->sockCli != INVALID_SOCKET){
  130. // 接收头部10字节
  131. char header[16] = { 0 };
  132. int nLen = 0;
  133. do {
  134. int tmp_len = 0;
  135. tmp_len = recv(pThis->sockCli, header + nLen, 12 - nLen, 0);
  136. if (tmp_len == 0) {// 链接关闭
  137. LOGE("关闭连接");
  138. if (pThis->m_pNotify)
  139. pThis->m_pNotify->OnNetNotify("{\"net_task_type\":\"systerm_notify\",\"net_task_cmd\":\"client_close\"}");
  140. closesocket(pThis->sockCli);
  141. pThis->sockCli = INVALID_SOCKET;
  142. return 0;
  143. }
  144. else if (tmp_len == SOCKET_ERROR){ // 出错
  145. int last_error = WSAGetLastError();
  146. if (last_error == WSAEWOULDBLOCK){
  147. continue;
  148. }
  149. else{
  150. LOGE("出错-关闭连接");
  151. closesocket(pThis->sockCli);
  152. pThis->sockCli = INVALID_SOCKET;
  153. if (pThis->m_pNotify)
  154. pThis->m_pNotify->OnNetNotify("{\"net_task_type\":\"systerm_notify\",\"net_task_cmd\":\"client_close\"}");
  155. return 0;
  156. }
  157. }
  158. nLen += tmp_len;
  159. } while (nLen<12 && !::InterlockedExchange((PLONG)&pThis->m_bexit, FALSE));
  160. LOGFMTI("接受头部信息:%s", header);
  161. if (strlen(header) == 12 && !::InterlockedExchange((PLONG)&pThis->m_bexit, FALSE)){
  162. int data_size = atoi(header);
  163. char *rcv_buf = new char[data_size + 1];
  164. memset(rcv_buf, 0, data_size + 1);
  165. nLen = 0;
  166. do {
  167. int tmp_len = 0;
  168. tmp_len = recv(pThis->sockCli, rcv_buf + nLen, data_size - nLen, 0);
  169. if (tmp_len == 0) {// 链接关闭
  170. if (pThis->m_pNotify)
  171. pThis->m_pNotify->OnNetNotify("{\"net_task_type\":\"systerm_notify\",\"net_task_cmd\":\"client_close\"}");
  172. closesocket(pThis->sockCli);
  173. pThis->sockCli = INVALID_SOCKET;
  174. delete[] rcv_buf;
  175. rcv_buf = NULL;
  176. return 0;
  177. }
  178. else if (tmp_len == SOCKET_ERROR){ // 出错
  179. int last_error = WSAGetLastError();
  180. if (last_error == WSAEWOULDBLOCK){
  181. continue;
  182. }
  183. else{
  184. closesocket(pThis->sockCli);
  185. pThis->sockCli = INVALID_SOCKET;
  186. if (pThis->m_pNotify)
  187. pThis->m_pNotify->OnNetNotify("{\"net_task_type\":\"systerm_notify\",\"net_task_cmd\":\"client_close\"}");
  188. delete[] rcv_buf;
  189. rcv_buf = NULL;
  190. return 0;
  191. }
  192. }
  193. nLen += tmp_len;
  194. } while (nLen < data_size&&!::InterlockedExchange((PLONG)&pThis->m_bexit, FALSE));
  195. LOGFMTI("接受信息:%s", rcv_buf);
  196. if (pThis->m_pNotify)
  197. pThis->m_pNotify->OnNetNotify(rcv_buf);
  198. delete[] rcv_buf;
  199. rcv_buf = NULL;
  200. }
  201. else{
  202. LOGFMTE("头部长度错误:%d, header=%s", strlen(header), header);
  203. }
  204. }
  205. }
  206. return 0;
  207. }
  208. void TCPServer::Stop()
  209. {
  210. LOGI("主动停止监听");
  211. if (sockSrv != INVALID_SOCKET){
  212. closesocket(sockSrv); sockSrv = INVALID_SOCKET;
  213. }
  214. if (sockCli != INVALID_SOCKET){
  215. closesocket(sockCli); sockCli = INVALID_SOCKET;
  216. }
  217. ::InterlockedExchange((PLONG)&m_bexit, TRUE);
  218. WaitForSingleObject(_listen_thread, INFINITE);
  219. WaitForSingleObject(_recv_thread, INFINITE);
  220. }
  221. //////////////////////////////////////////////////////////////////////////
  222. //////////////////////////////////////////////////////////////////////////
  223. TCPClient::TCPClient()
  224. {
  225. m_connected = FALSE;
  226. m_pNotify = NULL;
  227. }
  228. TCPClient::~TCPClient()
  229. {
  230. Stop();
  231. m_pNotify = NULL;
  232. }
  233. int TCPClient::InitNet(const char*ip, int port, INetNotify*pNotify)
  234. {
  235. m_pNotify = pNotify;
  236. sockConn = socket(AF_INET, SOCK_STREAM, 0);
  237. if (sockConn == INVALID_SOCKET){
  238. LOGE("create socket error");
  239. return -2;
  240. }
  241. SOCKADDR_IN addrSrv;
  242. addrSrv.sin_family = AF_INET;
  243. addrSrv.sin_addr.s_addr = inet_addr(ip);
  244. addrSrv.sin_port = htons(port);
  245. int err = connect(sockConn, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));
  246. if (err == INVALID_SOCKET){
  247. LOGE("connect server error");
  248. return -3;
  249. }
  250. ::InterlockedExchange((PLONG)&m_connected, TRUE);
  251. _loop_thread = (HANDLE)::_beginthreadex(NULL, 0, &TCPClient::LoopThread, this, 0, NULL);
  252. LOGI("连接成功-启动接受线程 LoopThread");
  253. return 0;
  254. }
  255. void TCPClient::Stop()
  256. {
  257. if (sockConn != INVALID_SOCKET){
  258. closesocket(sockConn);
  259. sockConn = INVALID_SOCKET;
  260. }
  261. ::InterlockedExchange((PLONG)&m_bexit, TRUE);
  262. ::WaitForSingleObject(_loop_thread, INFINITE);
  263. }
  264. int TCPClient::SendData(const char*data)
  265. {
  266. if (!m_connected){
  267. return -1;//未连接
  268. }
  269. if (sockConn == INVALID_SOCKET){
  270. return -2;
  271. }
  272. char header[16] = { 0 };
  273. int data_size = strlen(data);
  274. std::string str_data = data;
  275. sprintf_s(header, "%12d", data_size);
  276. int nLen = 0;
  277. AutoLock _lck(m_tx_send);
  278. do {
  279. int send_tmp_ = send(sockConn, header + nLen, 12 - nLen, 0);
  280. if (send_tmp_ == SOCKET_ERROR){
  281. int last_error = WSAGetLastError();
  282. if (last_error == WSAEWOULDBLOCK){
  283. continue;
  284. }
  285. else{
  286. closesocket(sockConn);
  287. sockConn = INVALID_SOCKET;
  288. return -3;
  289. }
  290. }
  291. else{
  292. nLen += send_tmp_;
  293. }
  294. } while (nLen < 12);
  295. nLen = 0;
  296. do {
  297. int send_tmp_ = send(sockConn, data + nLen, data_size - nLen, 0);
  298. if (send_tmp_ == SOCKET_ERROR){
  299. int last_error = WSAGetLastError();
  300. if (last_error == WSAEWOULDBLOCK){
  301. continue;
  302. }
  303. else{
  304. closesocket(sockConn);
  305. sockConn = INVALID_SOCKET;
  306. return -3;
  307. }
  308. }
  309. else{
  310. nLen += send_tmp_;
  311. }
  312. } while (nLen < data_size);
  313. return 0;
  314. }
  315. unsigned int TCPClient::LoopThread(PVOID param)
  316. {
  317. TCPClient*pThis = static_cast<TCPClient*>(param);
  318. while (!::InterlockedExchange((PLONG)&pThis->m_bexit, FALSE)){
  319. if (pThis->sockConn != INVALID_SOCKET){
  320. // 接收头部12字节
  321. char header[16] = { 0 };
  322. int nLen = 0;
  323. do {
  324. int tmp_len = 0;
  325. tmp_len = recv(pThis->sockConn, header + nLen, 12 - nLen, 0);
  326. if (tmp_len == 0) {// 链接关闭
  327. LOGE("关闭连接");
  328. if (pThis->m_pNotify){
  329. pThis->m_pNotify->OnNetNotify("{\"net_task_type\":\"systerm_notify\",\"net_task_cmd\":\"server_close\"}");
  330. }
  331. closesocket(pThis->sockConn);
  332. pThis->sockConn = INVALID_SOCKET;
  333. return 0;
  334. }
  335. else if (tmp_len == SOCKET_ERROR){ // 出错
  336. int last_error = WSAGetLastError();
  337. if (last_error == WSAEWOULDBLOCK){
  338. continue;
  339. }
  340. else{
  341. LOGE("出错-关闭连接");
  342. closesocket(pThis->sockConn);
  343. pThis->sockConn = INVALID_SOCKET;
  344. if (pThis->m_pNotify){
  345. pThis->m_pNotify->OnNetNotify("{\"net_task_type\":\"systerm_notify\",\"net_task_cmd\":\"server_error\"}");
  346. }
  347. return 0;
  348. }
  349. }
  350. nLen += tmp_len;
  351. } while (nLen < 12 && !::InterlockedExchange((PLONG)&pThis->m_bexit, FALSE));
  352. LOGFMTI("接收头部信息:%s", header);
  353. if (strlen(header) == 12 && !::InterlockedExchange((PLONG)&pThis->m_bexit, FALSE)){
  354. int data_size = atoi(header);
  355. char *rcv_buf = new char[data_size + 1];
  356. memset(rcv_buf, 0, data_size + 1);
  357. nLen = 0;
  358. do {
  359. int tmp_len = 0;
  360. tmp_len = recv(pThis->sockConn, rcv_buf + nLen, data_size - nLen, 0);
  361. if (tmp_len == 0) {// 链接关闭
  362. if (pThis->m_pNotify)
  363. pThis->m_pNotify->OnNetNotify("{\"net_task_type\":\"systerm_notify\",\"net_task_cmd\":\"server_close\"}");
  364. closesocket(pThis->sockConn);
  365. pThis->sockConn = INVALID_SOCKET;
  366. delete[] rcv_buf;
  367. rcv_buf = NULL;
  368. return 0;
  369. }
  370. else if (tmp_len == SOCKET_ERROR){ // 出错
  371. int last_error = WSAGetLastError();
  372. if (last_error == WSAEWOULDBLOCK){
  373. continue;
  374. }
  375. else{
  376. closesocket(pThis->sockConn);
  377. pThis->sockConn = INVALID_SOCKET;
  378. if (pThis->m_pNotify)
  379. pThis->m_pNotify->OnNetNotify("{\"net_task_type\":\"systerm_notify\",\"net_task_cmd\":\"server_error\"}");
  380. delete[] rcv_buf;
  381. rcv_buf = NULL;
  382. }
  383. return 0;
  384. }
  385. nLen += tmp_len;
  386. } while (nLen < data_size&&!::InterlockedExchange((PLONG)&pThis->m_bexit, FALSE));
  387. LOGFMTI("接收信息:%s", rcv_buf);
  388. if (pThis->m_pNotify)
  389. pThis->m_pNotify->OnNetNotify(rcv_buf);
  390. delete[] rcv_buf;
  391. rcv_buf = NULL;
  392. }
  393. else{
  394. LOGFMTE("头部长度错误:%d, header=%s", strlen(header), header);
  395. }
  396. }
  397. }
  398. return 0;
  399. }
  400. TCPClient* g_cli = NULL;
  401. TCPServer* g_srv = NULL;
  402. int NetOperator::InitServer(const char*ip, int port, INetNotify*pNotify)
  403. {
  404. if (g_srv != NULL){
  405. return -1;// 服务器已经启动
  406. }
  407. g_srv = new TCPServer;
  408. int nRet = g_srv->InitNet(ip, port, pNotify);
  409. if (nRet<0){
  410. delete g_srv; g_srv = NULL;
  411. }
  412. return nRet;
  413. }
  414. int NetOperator::InitClient(const char*ip, int port, INetNotify*pNotify)
  415. {
  416. if (g_cli != NULL){
  417. return -1;// client已经启动
  418. }
  419. g_cli = new TCPClient;
  420. int nRet = g_cli->InitNet(ip, port, pNotify);
  421. if (nRet <0){
  422. delete g_cli; g_cli = NULL;
  423. }
  424. return nRet;
  425. }
  426. void NetOperator::SetServerNotifyPtr(INetNotify*pNotify)
  427. {
  428. if (g_srv)
  429. g_srv->SetNotify(pNotify);
  430. }
  431. void NetOperator::SetClientNotifyPtr(INetNotify*pNotify)
  432. {
  433. if (g_cli)
  434. g_cli->SetNotify(pNotify);
  435. }
  436. void NetOperator::ServerStop()
  437. {
  438. if (g_srv){
  439. g_srv->Stop();
  440. delete g_srv;
  441. g_srv = NULL;
  442. }
  443. }
  444. int NetOperator::ServerSendData(const char*data)
  445. {
  446. int ret = -1;
  447. if (g_srv){
  448. ret = g_srv->SendData(data);
  449. }
  450. return ret;
  451. }
  452. void NetOperator::ClientStop()
  453. {
  454. if (g_cli){
  455. g_cli->Stop();
  456. delete g_cli;
  457. g_cli = NULL;
  458. }
  459. }
  460. int NetOperator::ClientSendData(const char*data)
  461. {
  462. int ret = -1;
  463. if (g_cli){
  464. ret = g_cli->SendData(data);
  465. }
  466. return ret;
  467. }