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

P2P编程

开发平台:

Visual C++

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