TCPConnWrapper.cpp
上传用户:liguizhu
上传日期:2015-11-01
资源大小:2422k
文件大小:8k
源码类别:

P2P编程

开发平台:

Visual C++

  1. #include "stdafx.h"
  2. #include "TCPConnWrapper.h"
  3. #pragma comment (lib, "Ws2_32.lib")
  4. namespace gaov
  5. {
  6. namespace chaos
  7. {
  8. int MySelect(SOCKET sock)
  9. {
  10. int n = (int)sock + 1;
  11. fd_set rfds, wfds;
  12. timeval tv = {10, 0}; // 设置超时时间为10s
  13. int err;
  14. while(true)
  15. {
  16. FD_ZERO(&rfds); //clear ReadSockSet to Zero
  17. FD_ZERO(&wfds); //clear WriteSockSet to Zero
  18. FD_SET(sock, &rfds); //add sock to ReadSockSet
  19. //FD_SET(sock, &wfds); //add sock to WriteSockSet
  20. err = select(n, &rfds, &wfds, NULL, &tv);
  21. switch (err)
  22. {
  23. case 0: // time limit expired
  24. return 0;
  25. case -1:// socket error.
  26. //error("select: %sn", strerror(errno));
  27. return -1;
  28. }
  29. if (FD_ISSET(sock, &rfds))
  30. return 1;
  31. else
  32. return 0;
  33. }
  34. }
  35. ////////////////////////////////
  36. /////////// TCPConn ////////////
  37. ////////////////////////////////
  38. bool TCPConn::InitNetwork()
  39. {
  40. WSADATA WsaData;
  41. if(WSAStartup(MAKEWORD(2, 2), &WsaData) != 0)
  42. return false;
  43. if(LOBYTE(WsaData.wVersion) != 2 || HIBYTE(WsaData.wVersion) != 2){
  44. WSACleanup();
  45. return false;
  46. }
  47. return true;
  48. }
  49. PSTREAM TCPConn::InitData(UINT maxlen)
  50. {
  51. if( !m_bNetworkInited ){
  52. if( !(m_bNetworkInited = InitNetwork()) )
  53. return NULL;
  54. }
  55. if (maxlen > out.size)
  56. {
  57. out.data = (UINT8 *) realloc(out.data, maxlen);
  58. if( ! out.data ) return NULL;
  59. out.size = maxlen;
  60. }
  61. out.p = out.data;
  62. out.end = out.data + out.size;
  63. return &out;
  64. }
  65. /* Send TCP transport data packet */
  66. int TCPConn::Send(PSTREAM s)
  67. {
  68. int length = int(s->end - s->data);
  69. int sent, total = 0;
  70. while (total < length)
  71. {
  72. sent = send(sock, (const char*)(s->data + total), length - total, 0);
  73. if (sent < 0) // socket error
  74. {
  75. closesocket(sock);
  76. return -1;
  77. }
  78. total += sent;
  79. }
  80. return 1;
  81. }
  82. /* Receive a message on the TCP layer */
  83. PSTREAM TCPConn::Recv(PSTREAM s, UINT length)
  84. {
  85. unsigned int new_length, end_offset, p_offset;
  86. int rcvd = 0;
  87. int err;
  88. if (s == NULL) /* read into "new" stream */
  89. {
  90. if (length > in.size)
  91. {
  92. in.data = (UINT8 *) realloc(in.data, length);
  93. if( ! in.data ) return NULL;
  94. in.size = length;
  95. }
  96. in.end = in.p = in.data;
  97. s = &in;
  98. }
  99. else /* append to existing stream */
  100. {
  101. new_length = int(s->end - s->data) + length;
  102. if (new_length > s->size)
  103. {
  104. p_offset = int(s->p - s->data);
  105. end_offset = int(s->end - s->data);
  106. s->data = (UINT8 *) realloc(s->data, new_length);
  107. if( ! s->data ) return NULL;
  108. s->size = new_length;
  109. s->p = s->data + p_offset;
  110. s->end = s->data + end_offset;
  111. }
  112. }
  113. while (length > 0)
  114. {
  115. err = MySelect(sock);
  116. if (err > 0)
  117. {
  118. rcvd = recv(sock, (char*)(s->end), length, 0);
  119. if (rcvd > 0)
  120. {
  121. s->end += rcvd;
  122. length -= rcvd;
  123. }
  124. else if(rcvd < 0) // socket error
  125. {
  126. closesocket(sock);
  127. sock = INVALID_SOCKET;
  128. return NULL;
  129. }
  130. else // Connection closed.
  131. return NULL;
  132. }
  133. else if( err < 0 ) // socket error
  134. {
  135. closesocket(sock);
  136. sock = INVALID_SOCKET;
  137. return NULL;
  138. }
  139. else
  140. return NULL;
  141. }
  142. return s;
  143. }
  144. ////////////////////////////////////////////////////
  145. /////////////////// TCPClient //////////////////////
  146. ////////////////////////////////////////////////////
  147. bool TCPClient::SendEx(UINT8 msgType, UINT8 subMsgType, PBYTE data, UINT dataLen)
  148. {
  149. PSTREAM s = InitData( dataLen + 6 );
  150. if( !s )
  151. return false;
  152. // Header: 6 bytes
  153. out_uint8(s, msgType);
  154. out_uint8(s, subMsgType);
  155. out_uint32_be(s, dataLen);
  156. // Data
  157. if( dataLen>0 && data ) 
  158. out_uint8p(s, data, dataLen);
  159. s_mark_end(s);
  160. if( Send(s) <= 0 )
  161. return false;
  162. return true;
  163. }
  164. bool TCPClient::SendEx2(UINT8 msgType, UINT8 subMsgType, PBYTE data1, UINT dataLen1, PBYTE data2, UINT dataLen2)
  165. {
  166. UINT dataLen = dataLen1 + dataLen2;
  167. PSTREAM s = InitData( dataLen + 4*2 + 6 );
  168. if( !s )
  169. return false;
  170. // Header: 6 bytes
  171. out_uint8(s, msgType);
  172. out_uint8(s, subMsgType);
  173. out_uint32_be(s, dataLen); // dataLen = dataLen1 + dataLen2
  174. if( dataLen > 0 )
  175. {
  176. // Data1
  177. out_uint32_be(s, dataLen1);
  178. if(dataLen1>0 && data1) 
  179. out_uint8p(s, data1, dataLen1);
  180. // Data2
  181. out_uint32_be(s, dataLen2);
  182. if(dataLen2>0 && data2) 
  183. out_uint8p(s, data2, dataLen2);
  184. }
  185. s_mark_end(s);
  186. if( Send(s) <= 0 )
  187. return false;
  188. return true;
  189. }
  190. bool TCPClient::RecvEx(UINT8& msgType, UINT8& subMsgType, PBYTE& data, UINT& dataLen, const bool bRecvData/*=true*/)
  191. {
  192. PSTREAM s = Recv(NULL, 6);
  193. if( ! s )
  194. return false;
  195. in_uint8(s, msgType);
  196. in_uint8(s, subMsgType);
  197. in_uint32_be(s, dataLen);
  198. if( dataLen>0 && bRecvData )
  199. {
  200. s = Recv(s, dataLen);
  201. if( ! s )
  202. return false;
  203. in_uint8p(s, data, dataLen);
  204. }
  205. return true;
  206. }
  207. bool TCPClient::RecvEx2(UINT8& msgType, UINT8& subMsgType, PBYTE& data1, UINT& dataLen1, 
  208. PBYTE& data2, UINT& dataLen2, const bool bRecvData/*=true*/ )
  209. {
  210. PSTREAM s = Recv(NULL, 6);
  211. if( ! s ) 
  212. return false;
  213. in_uint8(s, msgType);
  214. in_uint8(s, subMsgType);
  215. UINT totalLen;
  216. in_uint32_be(s, totalLen);  // totalLen: dataLen1 + dataLen2
  217. if( totalLen > 0 )
  218. {
  219. s = Recv(s, totalLen + 4*2);
  220. if( ! s )
  221. return false;
  222. // Data1
  223. in_uint32_be(s, dataLen1);
  224. if(dataLen1>0 && bRecvData) 
  225. in_uint8p(s, data1, dataLen1);
  226. // Data2
  227. in_uint32_be(s, dataLen2);
  228. if(dataLen2>0 && bRecvData) 
  229. in_uint8p(s, data2, dataLen2);
  230. }
  231. return true;
  232. }
  233. /* Establish a connection on the TCP layer */
  234. // -3 : init network failed
  235. // -2 : connection exists; 
  236. // -1 : sock error
  237. // 0 : mem error
  238. // 1 : success
  239. int TCPClient::Connect(const char* sIP, USHORT port)
  240. {
  241. if( !m_bNetworkInited ){
  242. if( !(m_bNetworkInited = InitNetwork()) )
  243. return -3;
  244. }
  245. if( sock!=INVALID_SOCKET ) // exists
  246. return -2;
  247. if ( (sock = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET ){
  248. int lastErr = WSAGetLastError();
  249. //error("socket: %sn", strerror(errno));
  250. return -1;
  251. }
  252. sockaddr_in addr;
  253. memset(&addr, 0, sizeof(addr));
  254. addr.sin_family = AF_INET;
  255. addr.sin_addr.s_addr = inet_addr(sIP);
  256. addr.sin_port = htons(port);
  257. if (connect(sock, (struct sockaddr *) &addr, sizeof(struct sockaddr)) < 0){
  258. //error("connect: %sn", strerror(errno));
  259. int lastErr = WSAGetLastError();
  260. closesocket(sock);
  261. sock = INVALID_SOCKET;
  262. return -1;
  263. }
  264. int true_value = 1;
  265. setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (const char *) &true_value, sizeof(true_value));
  266. in.size = 4096;
  267. in.data = (UINT8 *) malloc(in.size);
  268. if( ! in.data ) return 0;
  269. out.size = 4096;
  270. out.data = (UINT8 *) malloc(out.size);
  271. if( ! out.data ) return 0;
  272. return 1;
  273. }
  274. ////////////////////////////////////////////////////
  275. /////////////////// TCPServer //////////////////////
  276. ////////////////////////////////////////////////////
  277. bool TCPServer::Listen(const char* sIP, USHORT port)
  278. {
  279. if( !m_bNetworkInited ){
  280. if( !(m_bNetworkInited = InitNetwork()) )
  281. return false;
  282. }
  283. // already exists
  284. if( sock!=INVALID_SOCKET )
  285. return false;
  286. sock = socket(AF_INET, SOCK_STREAM, 0);
  287. if( INVALID_SOCKET==sock )
  288. return false;
  289. struct sockaddr_in addr;
  290. int addrLen = sizeof(addr);
  291. memset(&addr, 0, addrLen);
  292. addr.sin_family = AF_INET;
  293. addr.sin_addr.s_addr = inet_addr(sIP);
  294. addr.sin_port = htons(port);
  295. if( bind(sock, (sockaddr *)&addr, addrLen) == SOCKET_ERROR )
  296. return false;
  297. if( listen(sock, 5) == SOCKET_ERROR )
  298. return false;
  299. return true;
  300. }
  301. SOCKET TCPServer::Accept()
  302. {
  303. if( !m_bNetworkInited || sock==INVALID_SOCKET )
  304. return INVALID_SOCKET;
  305. return accept( sock, NULL, NULL );
  306. }
  307. };
  308. };