CWorkerSocket.cpp
上传用户:hhs829
上传日期:2022-06-17
资源大小:586k
文件大小:7k
源码类别:

DirextX编程

开发平台:

Visual C++

  1. // 
  2. // CWorkerSocket.cpp
  3. // 
  4. #include "stdafx.h"
  5. #include "CWorkerSocket.h"
  6. #ifdef _DEBUG
  7. #define new DEBUG_NEW
  8. #undef THIS_FILE
  9. static char THIS_FILE[] = __FILE__;
  10. #endif
  11. //////////////////////////////////////////////////////////////////////////////
  12. CWorkerSocket::CWorkerSocket()
  13. {
  14. m_hSocket      = NULL;
  15. m_bReceiving   = false;
  16. m_bSending     = false;
  17. // Initialize thread event
  18. m_hThrdFinish = ::CreateEvent(NULL,    // pointer to security attributes 
  19.      TRUE,      // flag for manual-reset event 
  20. FALSE,     // flag for initial state 
  21. NULL);     // pointer to event-object name
  22. m_hSendFinish = ::CreateEvent(NULL, 
  23.      TRUE, 
  24. FALSE, 
  25. NULL); 
  26. }
  27. CWorkerSocket::~CWorkerSocket()
  28. {
  29. // Close the socket
  30. Disconnect();
  31. // Release the thread event
  32. if (m_hThrdFinish)
  33. {
  34. CloseHandle(m_hThrdFinish);
  35. m_hThrdFinish = NULL;
  36. }
  37. if (m_hSendFinish)
  38. {
  39. CloseHandle(m_hSendFinish);
  40. m_hSendFinish = NULL;
  41. }
  42. }
  43. // Attach a connected sockt to this object
  44. bool CWorkerSocket::Attach(SOCKET inSock)
  45. {
  46. if (m_hSocket == NULL)
  47. {
  48. m_hSocket = inSock;
  49. return true;
  50. }
  51. return false;
  52. }
  53. SOCKET CWorkerSocket::Detach(void)
  54. {
  55. SOCKET hSock = m_hSocket;
  56. m_hSocket    = NULL;
  57. return hSock;
  58. }
  59. // Send data on connected sockets, blockingly
  60. int CWorkerSocket::Send(char * inData, int inLen)
  61. {
  62. if (m_hSocket)
  63. {
  64. char * pData = inData; //new char[inLen];
  65. if (!pData)
  66. return E_SOCKET_FAIL;
  67. TIMEVAL tm;
  68. fd_set wfds;
  69. FD_ZERO(&wfds);
  70. FD_SET(m_hSocket, &wfds);
  71. tm.tv_sec  = 1;
  72. tm.tv_usec = 0;
  73. // Make sure the current socket can write
  74. if (select(0, NULL, &wfds, NULL, &tm))
  75. {
  76. int nret   = 0;
  77. int nCount = inLen;
  78. do 
  79. {
  80. nret = send(m_hSocket, pData, nCount, 0);
  81. if (nret == SOCKET_ERROR)
  82. {
  83. return E_SOCKET_FAIL;
  84. }
  85. nCount -= nret;
  86. pData  += nret;
  87. if (nCount > 0) 
  88. Sleep(20);
  89. } while (nCount > 0);
  90. return S_SOCKET_OK;
  91. }
  92. else
  93. {
  94. // The socket cannot write currently
  95. return E_SOCKET_NOT_READY;
  96. }
  97. }
  98. return E_SOCKET_FAIL;
  99. }
  100. int CWorkerSocket::Receive(char * outBuf, int inLen)
  101. {
  102. if (m_hSocket)
  103. {
  104. // Check socket for readability 
  105. TIMEVAL tv;
  106. tv.tv_sec  = 0;
  107. tv.tv_usec = 0;
  108. fd_set rfds;
  109. FD_ZERO(&rfds);
  110. FD_SET(m_hSocket, &rfds);
  111. if (select(1, &rfds, NULL, NULL,&tv))
  112. {
  113. int    nCount = inLen;
  114. int    lenret = 0;
  115. char * pBuf   = outBuf;
  116. do 
  117. {
  118. lenret = recv(m_hSocket, pBuf, nCount, 0);
  119. if (lenret == SOCKET_ERROR) 
  120. {
  121. return E_SOCKET_FAIL;
  122. }
  123. else if (lenret == 0)
  124. {
  125. // Indicate the socket disconnected
  126. return E_SOCKET_CLOSE;
  127. }
  128. nCount -= lenret;
  129. pBuf   += lenret;
  130. if (nCount > 0) 
  131. Sleep(20);
  132. } while (nCount > 0);
  133. return S_SOCKET_OK;
  134. }
  135. else
  136. {
  137. // The socket not ready to read
  138. return E_SOCKET_NOT_READY;
  139. }
  140. }
  141. return E_SOCKET_FAIL;
  142. }
  143. void CWorkerSocket::Disconnect(void)
  144. {
  145. if (m_hSocket)
  146. {
  147. // Terminate receiving and sending thread if necessary
  148. if (m_bReceiving)
  149. StopReceiving();
  150. if (m_bSending)
  151. StopSending();
  152. closesocket(m_hSocket);
  153. m_hSocket = NULL;
  154. }
  155. }
  156. // Connect to the remote socket
  157. bool CWorkerSocket::Connect(char * inTarget, int inPort)
  158. {
  159. Disconnect();
  160. // Create a new socket to connection
  161. m_hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  162. if (m_hSocket == INVALID_SOCKET)
  163. {
  164. m_hSocket = NULL;
  165. return false;
  166. }
  167. BOOL sopt = TRUE;
  168. setsockopt(m_hSocket, IPPROTO_TCP, TCP_NODELAY, (char *)&sopt, sizeof(BOOL));
  169. setsockopt(m_hSocket, SOL_SOCKET, SO_DONTLINGER, (char *)&sopt, sizeof(BOOL));
  170. // Resolve hostname
  171. DWORD  addr = inet_addr(inTarget);
  172. if (addr == INADDR_NONE) 
  173. {
  174. struct hostent *he = gethostbyname(inTarget);
  175. if (he == NULL) 
  176. {
  177. closesocket(m_hSocket);
  178. m_hSocket = NULL;
  179. return false;
  180. }
  181. addr = *(DWORD *)(he->h_addr_list[0]);
  182. }
  183. // Create socket address
  184. SOCKADDR_IN   saddr;
  185. memset(&saddr, 0, sizeof(SOCKADDR_IN));
  186. saddr.sin_addr.S_un.S_addr = addr;
  187. saddr.sin_family           = AF_INET;
  188. saddr.sin_port             = htons((WORD)inPort);
  189. // Connect to the remote host
  190. if (connect(m_hSocket, (SOCKADDR *)&saddr, sizeof(SOCKADDR_IN)) != 0) 
  191. {
  192. closesocket(m_hSocket);
  193. m_hSocket = NULL;
  194. return false;
  195. }
  196. return true;
  197. }
  198. ////////////////////////////////////////////////////////////////////////////
  199. // Start a data receiving thread
  200. bool CWorkerSocket::StartReceiving(void)
  201. {
  202. if (m_hSocket)
  203. {
  204. if (m_bReceiving)
  205. return true;
  206. m_bReceiving = true;
  207. ResetEvent(m_hThrdFinish);
  208. // Make socket blocking safely
  209. u_long   nonBlock = FALSE;
  210. ioctlsocket(m_hSocket, FIONBIO, &nonBlock);
  211. AfxBeginThread((AFX_THREADPROC)CWorkerSocket::ReceivingThrd, this);
  212. return true;
  213. }
  214. return false;
  215. }
  216. bool CWorkerSocket::StopReceiving(void)
  217. {
  218. if (m_hSocket)
  219. {
  220. if (!m_bReceiving)
  221. return true;
  222. m_bReceiving = false;
  223. // Make socket nonblocking to terminate receiving thread
  224. char pData[sizeof(MSG_HEADER)];
  225. PMSG_HEADER pMsg = (PMSG_HEADER) pData;
  226. pMsg->nDataSize  = 0;
  227. pMsg->nMsgType   = RECV_EXIT_REQUEST;
  228. Send(pData, sizeof(MSG_HEADER));
  229. // u_long   nonBlock = TRUE;
  230. // ioctlsocket(m_hSocket, FIONBIO, &nonBlock);
  231. WaitForSingleObject(m_hThrdFinish, 2000);
  232. // Restore to blocking socket
  233. // nonBlock = FALSE;
  234. // ioctlsocket(m_hSocket, FIONBIO, &nonBlock);
  235. return true;
  236. }
  237. return false;
  238. }
  239. // Virtual method, receive loop
  240. void CWorkerSocket::ReceivingLoop(void)
  241. {
  242. }
  243. UINT CWorkerSocket::ReceivingThrd(void * pParam)
  244. {
  245. CWorkerSocket * pSock = (CWorkerSocket *) pParam;
  246. if (pSock != NULL)
  247. {
  248. pSock->ReceivingLoop();
  249. }
  250. SetEvent(pSock->m_hThrdFinish);
  251. return 1;
  252. }
  253. ////////////////////////////////////////////////////////////////////////////
  254. bool CWorkerSocket::StartSending(void)
  255. {
  256. if (m_hSocket)
  257. {
  258. if (m_bSending)
  259. return true;
  260. m_bSending = true;
  261. ResetEvent(m_hSendFinish);
  262. // Make socket blocking safely
  263. // u_long   nonBlock = FALSE;
  264. // ioctlsocket(m_hSocket, FIONBIO, &nonBlock);
  265. AfxBeginThread((AFX_THREADPROC)CWorkerSocket::SendingThrd, this);
  266. return true;
  267. }
  268. return false;
  269. }
  270. bool CWorkerSocket::StopSending(void)
  271. {
  272. if (m_hSocket)
  273. {
  274. if (!m_bSending)
  275. return true;
  276. m_bSending = false;
  277. // Make socket nonblocking to terminate sending thread
  278. // u_long   nonBlock = TRUE;
  279. // ioctlsocket(m_hSocket, FIONBIO, &nonBlock);
  280. WaitForSingleObject(m_hSendFinish, 2000);
  281. // Restore to blocking socket
  282. // nonBlock = FALSE;
  283. // ioctlsocket(m_hSocket, FIONBIO, &nonBlock);
  284. return true;
  285. }
  286. return false;
  287. }
  288. // Virtual method: data-sending loop
  289. void CWorkerSocket::SendingLoop(void)
  290. {
  291. }
  292. UINT CWorkerSocket::SendingThrd(void * pParam)
  293. {
  294. CWorkerSocket * pSock = (CWorkerSocket *) pParam;
  295. if (pSock != NULL)
  296. {
  297. pSock->SendingLoop();
  298. }
  299. SetEvent(pSock->m_hSendFinish);
  300. return 1;
  301. }