TCP.cpp
上传用户:hnzycx
上传日期:2022-08-09
资源大小:12567k
文件大小:3k
开发平台:

Visual C++

  1. #include "StdAfx.h"
  2. #include "TCP.h"
  3. CTCP::CTCP(void)
  4. {
  5. //初始化socket环境
  6. WSADATA wsd;
  7. WSAStartup(MAKEWORD(1,1),&wsd);
  8. //创建线程退出事件句柄
  9. m_exitThreadEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
  10. }
  11. CTCP::~CTCP(void)
  12. {
  13. //释放socket资源
  14. WSACleanup();
  15. //关闭线程退出事件句柄
  16. CloseHandle(m_exitThreadEvent);
  17. }
  18. //此线程用于监视客户端通讯的事件
  19. DWORD CTCP::SocketThreadFunc(LPVOID lparam)
  20. {
  21. CTCP *pSocket;
  22. pSocket = (CTCP*)lparam;
  23. fd_set fdRead;
  24. int ret;
  25. TIMEVAL aTime;
  26. aTime.tv_sec = 1;
  27. aTime.tv_usec = 0;
  28. while (TRUE)
  29. {
  30. if (WaitForSingleObject(pSocket->m_exitThreadEvent,0) == WAIT_OBJECT_0)
  31. {
  32. break;
  33. }
  34. FD_ZERO(&fdRead);
  35. FD_SET(pSocket->m_socket,&fdRead);
  36. ret = select (0,&fdRead,NULL,NULL,&aTime);
  37. if (ret == SOCKET_ERROR)
  38. {
  39. pSocket->OnError(pSocket->m_pOwnerWnd,1);
  40. pSocket->OnDisConnect(pSocket->m_pOwnerWnd);
  41. closesocket(pSocket->m_socket);
  42. break;
  43. }
  44. if (ret>0)
  45. {
  46. if (FD_ISSET(pSocket->m_socket,&fdRead))
  47. {
  48. char recvBuf[1024];
  49. int recvLen;
  50. ZeroMemory(recvBuf,1024);
  51. recvLen = recv(pSocket->m_socket,recvBuf,1024,0);
  52. if (recvLen == SOCKET_ERROR)
  53. {
  54. int Ierror = WSAGetLastError();
  55. pSocket->OnError(pSocket->m_pOwnerWnd,Ierror);
  56. pSocket->OnDisConnect(pSocket->m_pOwnerWnd);
  57. closesocket(pSocket->m_socket);
  58. break;
  59. }
  60. else if (recvLen == 0)
  61. {
  62. pSocket->OnDisConnect(pSocket->m_pOwnerWnd);
  63. closesocket(pSocket->m_socket);
  64. }
  65. else
  66. {
  67. pSocket->OnRead(pSocket->m_pOwnerWnd,recvBuf,recvLen);
  68. }
  69. }
  70. }
  71. }
  72. return 0;
  73. }
  74. //打开客户端socket
  75. bool CTCP::Open(CWnd *pWnd)
  76. {
  77. //复位线程退出事件
  78. ResetEvent(m_exitThreadEvent);
  79. //存储父窗口句柄
  80. m_pOwnerWnd = pWnd;
  81. //创建tcp套接字
  82. m_socket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
  83. if (m_socket == SOCKET_ERROR)
  84. {
  85. return FALSE;
  86. }
  87. //创建通讯线程
  88. tcpThreadHandle = CreateThread(NULL,0,SocketThreadFunc,this,0,NULL);
  89. if (tcpThreadHandle == NULL)
  90. {
  91. closesocket(m_socket);
  92. return FALSE;
  93. }
  94. return TRUE;
  95. }
  96. //关闭客户端socket
  97. bool CTCP::Close()
  98. {
  99. //发送线程退出事件
  100. SetEvent(m_exitThreadEvent);
  101. Sleep(1000);
  102. //关闭socket,释放资源
  103. int err = closesocket(m_socket);
  104. if (err == SOCKET_ERROR)
  105. {
  106. return FALSE;
  107. }
  108. return TRUE;
  109. }
  110. //建立与服务器的连接
  111. bool CTCP::Connect()
  112. {
  113. struct sockaddr_in addr;
  114. int err;
  115. addr.sin_family = AF_INET;
  116. addr.sin_port = htons(m_port);
  117. //此处要将双字节转换成单字节
  118. char ansiRemoteHost[255];
  119. ZeroMemory(ansiRemoteHost,255);
  120. WideCharToMultiByte(CP_ACP,WC_COMPOSITECHECK,m_remoteHost,wcslen(m_remoteHost),ansiRemoteHost,wcslen(m_remoteHost),NULL,NULL);
  121. addr.sin_addr.s_addr = inet_addr(ansiRemoteHost);
  122. //此时采用同步连接方式,connect直接返回成功或是失败
  123. err = connect(m_socket,(struct sockaddr *)&addr,sizeof(addr));
  124. if (err == SOCKET_ERROR)
  125. {
  126. return FALSE;
  127. }
  128. //设置通讯模式为异步模式
  129. DWORD ul = 1;
  130. ioctlsocket(m_socket,FIONBIO,&ul);
  131. return TRUE;
  132. }
  133. //向服务器发送数据
  134. bool CTCP::SendData(const char *buf, int len)
  135. {
  136. send(m_socket,buf,len,0);
  137. return TRUE;
  138. }