tcp.cpp
上传用户:feituo2008
上传日期:2013-02-02
资源大小:493k
文件大小:12k
源码类别:

Email客户端

开发平台:

Visual C++

  1. #include "stdafx.h"
  2. #include <winsock.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <time.h>
  6. #include "util.h"
  7. #include "tcp.h"
  8. extern WriteLog(char *file_name, char *format, ...);
  9. extern WriteStat(char *format, ...);
  10. int wsa_ok =0;
  11. void peek_message(void);
  12. int get_local_ip(char *ip);
  13. class CTcpInit
  14. {
  15. public:
  16. CTcpInit()
  17. {
  18. tcp_init();
  19. }
  20. ~CTcpInit()
  21. {
  22. tcp_exit();
  23. }
  24. };
  25. CTcpInit g_ttt;
  26. int tcp_init()
  27. {
  28.     WSAData wsa;
  29.     //sd_bind =sd_connect =sd_accept =-1;
  30.     if(WSAStartup(MAKEWORD(1, 1), &wsa) !=0)
  31.         return -1;
  32.     wsa_ok =1;
  33. return 0;
  34. }
  35. int tcp_exit()
  36. {
  37.   if(wsa_ok) WSACleanup();
  38.   return 0;
  39. }
  40. int tcp_status(int  sd, char *type, int timeout)
  41. {
  42.   fd_set rset, wset, eset;
  43.   fd_set FAR *prset =NULL, *pwset =NULL, *peset =NULL;
  44.   struct timeval tval;
  45.   int i, status, err_no =0;
  46.   time_t t1, t2;
  47.   MSG msg;
  48.   tval.tv_sec =0;
  49.   tval.tv_usec =1;
  50.   time(&t1);
  51.   t2 =t1;
  52.   while(t2-t1 < timeout)
  53.   {
  54.     FD_ZERO(&rset);
  55.     FD_ZERO(&wset);
  56.     FD_ZERO(&eset);
  57.     for(i =0; i<(int)strlen(type); i++)
  58.     {
  59.       if(type[i] =='r') { FD_SET(sd, &rset); prset =&rset; }
  60.       if(type[i] =='w') { FD_SET(sd, &wset); pwset =&wset; }
  61.       if(type[i] =='e') { FD_SET(sd, &eset); peset =&eset; }
  62.     }
  63.     status =select(-1, prset, pwset, peset, &tval);
  64. err_no =WSAGetLastError();
  65. int err=GetLastError();
  66. //WriteStat("select err_no=%d, err=%d", err_no, err);
  67.     time(&t2);
  68. if(status ==0)
  69.     {
  70.       if(PeekMessage(&msg, 0, NULL, NULL, PM_REMOVE))
  71.       {
  72.         TranslateMessage(&msg);
  73.         DispatchMessage(&msg);
  74.         if(msg.message ==WM_QUIT)
  75. {
  76. //WSASetLastError(WSAETIMEOUT);
  77. return -1;
  78. }
  79.       }
  80.       if(t2-t1 <timeout) continue;
  81.       else
  82.       {
  83.         if(prset) FD_CLR((UINT)sd,&rset);
  84.         if(pwset) FD_CLR((UINT)sd,&wset);
  85.         if(peset) FD_CLR((UINT)sd,&eset);
  86.         WSASetLastError(WSAEWOULDBLOCK);
  87.         return -10;
  88.       }
  89.     }
  90.     if(peset && FD_ISSET(sd, peset))
  91.     {
  92.       if(prset !=NULL) FD_CLR((UINT)sd,&rset);
  93.       if(pwset !=NULL) FD_CLR((UINT)sd,&wset);
  94.       if(peset !=NULL) FD_CLR((UINT)sd,&eset);
  95.       //err_no =WSAGetLastError();
  96.       /*
  97.       len =sizeof(errno);
  98.       getsockopt(sd, SOL_SOCKET, SO_ERROR, (char *)&errno, &len);
  99.       */
  100.   WSASetLastError(err_no);
  101.       return -1;
  102.     }
  103.     if((prset && FD_ISSET(sd, prset)) || (pwset && FD_ISSET(sd, pwset)))
  104.     {
  105.       //err_no =WSAGetLastError();
  106.       /*
  107.       len =sizeof(errno);
  108.       getsockopt(sd, SOL_SOCKET, SO_ERROR, (char *)&errno, &len);
  109.       */
  110.     }
  111.     if(prset !=NULL) FD_CLR((UINT)sd,&rset);
  112.     if(pwset !=NULL) FD_CLR((UINT)sd,&wset);
  113.     if(peset !=NULL) FD_CLR((UINT)sd,&eset);
  114.     //if(status <0)
  115.       //err_no =WSAGetLastError();
  116. WSASetLastError(err_no);
  117.     if(err_no ==WSAEINTR)
  118. {
  119. return WSAEINTR;
  120. }
  121.     if(err_no)
  122.     {
  123.       return -1;
  124.     }
  125.     else break;
  126.   }
  127.   return 0;
  128. }
  129. int tcp_bind(HWND hWnd, int port)
  130. {
  131. struct sockaddr_in addr;
  132.     char temp[200];
  133.     int sd;
  134.     sd =-1;
  135. if((sd =(int)socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) <0)
  136. {
  137. sprintf(temp, "socket failed! errno:%d", WSAGetLastError());
  138. return -1;
  139. }
  140. memset(&addr, 0, sizeof(addr));
  141. addr.sin_family =AF_INET;
  142. addr.sin_port =htons((unsigned short)port);
  143.     int l =1;
  144.     setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, (char *)&l, sizeof(l));
  145.     /*setsockopt(sd, SOL_SOCKET, SO_REUSEPORT, (char *)&l, sizeof(l));*/
  146. if(bind(sd, (struct sockaddr *)&addr, sizeof(addr)) <0)
  147. {
  148.       sprintf(temp, "bind failed! errno:%d", WSAGetLastError());
  149.   closesocket(sd);
  150.       return -1;
  151. }
  152. if(hWnd && WSAAsyncSelect(sd, hWnd, WM_TCP, FD_ACCEPT) !=0)
  153.     {
  154.       sprintf(temp, "tcp_bind:WSAAsyncSelect failed!");
  155.       closesocket(sd);
  156.       return -2;
  157.     }
  158.     //sd_bind =sd;
  159.     listen(sd, 5);
  160.     return sd;
  161. }
  162. int tcp_accept(int sd, int timeout)
  163. {
  164.   int sd_acc =-1;
  165.   struct sockaddr_in sa;
  166.   int len;
  167.   /*unsigned long l;*/
  168.   if(tcp_status(sd, "rw", timeout) <0)
  169.     return -1;
  170.   len =sizeof(sa);
  171.   if((sd_acc =(int)accept(sd, (struct sockaddr *)&sa, &len)) <0)
  172.     return -1;
  173.   //sd_accept =sd_acc;
  174.   /*  l =1;
  175.     if(ioctlsocket(sd_acc, FIONBIO, &l) <0)
  176.     {
  177.       closesocket(sd);
  178.       return -1;
  179.     }*/
  180.   return sd_acc;
  181. }
  182. int tcp_connect(char *hostname, int port, int timeout, int f_noblock)
  183. {
  184.     struct hostent *hp;
  185.     struct sockaddr_in addr;
  186.     char temp[200];
  187.     unsigned long ul;
  188.     long l;
  189.     int sd =-1, ret;
  190.     time_t t1, t2;
  191.     sd =-1;
  192. memset(&addr, 0, sizeof(addr));
  193. if((sd =(int)socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) <0)
  194. {
  195. sprintf(temp, "socket failed! errno:%d", WSAGetLastError());
  196. return -1;
  197. }
  198. memset(&addr, 0, sizeof(addr));
  199.     ul =inet_addr(hostname);
  200.     if(ul ==0xffffffff)
  201.     {
  202.   if((hp =gethostbyname(hostname)) ==NULL)
  203.   {
  204.         sprintf(temp, "gethostbyname and inet_addr failed! errno:%d", WSAGetLastError());
  205.     closesocket(sd);
  206.         return -1;
  207.       }
  208.   memcpy(&addr.sin_addr, hp->h_addr, hp->h_length);
  209. }
  210.     else  addr.sin_addr.s_addr=ul;
  211. addr.sin_family =PF_INET;
  212. addr.sin_port =htons((unsigned short)port);
  213.     l =1;
  214.     if(f_noblock && ioctlsocket(sd, FIONBIO, (unsigned long *)&l) <0)
  215.     {
  216.       closesocket(sd);
  217.       return -1;
  218.     }
  219. /*if(setsockopt(sd, IPPROTO_TCP, TCP_NODELAY, (char *)&l, sizeof(l)) <0)
  220.     {
  221.       closesocket(sd);
  222.       return -1;
  223.     }*/
  224.     time(&t1);
  225.     while((ret =connect(sd, (struct sockaddr *)&addr, sizeof(addr))) !=0)
  226.     {
  227.       time(&t2);
  228.       if((t2 -t1) > timeout)
  229.       {
  230.         closesocket(sd);
  231.         return -1;
  232.       }
  233.       peek_message();
  234.       int err_no =WSAGetLastError();
  235.   if(ret ==SOCKET_ERROR)
  236.   {
  237.   if(err_no ==WSAEISCONN) break;
  238.       else if(err_no ==WSAEWOULDBLOCK /*|| err_no ==WSAEINPROGRESS*/ || err_no ==WSAEALREADY)
  239.              continue;
  240.           else
  241.       {
  242. //  char temp[256];
  243.     //GetErrString(temp, err_no);
  244. closesocket(sd);
  245.         return -1;
  246.       }
  247.   }
  248. }
  249.     if(tcp_status(sd, "we", timeout) <0)
  250.     {
  251.       sprintf(temp, "status:连接服务器失败!n检查服务器端程序是否运行n且主机地址是否%s, 端口是否%dn"
  252.                     "errno=%d",
  253.             hostname, port, WSAGetLastError());
  254.       closesocket(sd);
  255.       return -1;
  256.     }
  257.     //sd_connect =sd;
  258.     return sd;
  259. }
  260. void tcp_close(int sd)
  261. {
  262. tcp_disconnect(sd);
  263. }
  264. void tcp_disconnect(int sd)
  265. {
  266.   if(sd >0)
  267.   {
  268.     closesocket(sd);
  269.     //if(sd ==sd_connect) sd_connect =-1;
  270.     //if(sd ==sd_accept) sd_accept =-1;
  271.     //if(sd ==sd_bind) sd_bind =-1;
  272.   }
  273. }
  274. int tcp_send(int sd, char *buf, int len, int timeout)
  275. {
  276.   int len1, len_send =0;
  277.   time_t t1, t2;
  278.   len_send =0;
  279.   time(&t1);
  280.   t2 =t1;
  281.   //WriteLog("comm.log", "tcp_send:len=%d", len);
  282.   while(len_send <len)
  283.   {
  284.     if(t2-t1 >timeout)
  285.       return len_send;
  286.     if(tcp_status(sd, "w", timeout-(int)(t2-t1)) <0)
  287. {
  288.       return len_send;
  289. }
  290.     if((len1 =send(sd, &buf[len_send], len-len_send, 0)) <=0)
  291.     {
  292.       if(len1 ==SOCKET_ERROR && GetLastError() ==WSAEWOULDBLOCK)
  293.       {
  294.         time(&t2);
  295.         continue;
  296.       }
  297.       return len_send;
  298.     }
  299.     len_send +=len1;
  300.     time(&t2);
  301.   }
  302.   return len_send;
  303. }
  304. int tcp_recv(int sd, char *buf, int len, int timeout)
  305. {
  306.   int len1, len_recv;
  307.   time_t t2, t1;
  308.   len_recv =0;
  309.   time(&t1);
  310.   t2 =t1;
  311.   int err =0;
  312.   while(len_recv <len)
  313.   {
  314.     if(timeout >0)
  315. {
  316. if(t2 -t1 >timeout)
  317. {
  318. WSASetLastError(err);
  319. if(len_recv ==0) return -1;
  320. return len_recv;
  321. }
  322. if(tcp_status(sd, "r", timeout-(int)(t2-t1)) <0)
  323. {
  324. err =WSAGetLastError();
  325. //WriteStat("tcp_status err=%d", WSAGetLastError());
  326. WSASetLastError(err);
  327. if(len_recv ==0) return -1;
  328. return len_recv;
  329. }
  330. }
  331.      if((len1 =recv(sd, &buf[len_recv], len-len_recv, 0)) <=0)
  332.      {
  333. err =WSAGetLastError();
  334. //WriteStat("recv err=%d, len1=%d", err, len1);
  335.        if(timeout ==0) break;
  336.        if(len1 ==SOCKET_ERROR && err ==WSAEWOULDBLOCK)
  337.        {
  338.          time(&t2);
  339.          if(timeout <=0) break;
  340.  continue;
  341.        }
  342.    WSASetLastError(err);
  343.       if(len_recv ==0) return -1;
  344.        return len_recv;
  345.     }
  346.     len_recv +=len1;
  347.     if(timeout <=0) break;
  348.     time(&t2);
  349.   }
  350.   WSASetLastError(err);
  351.   if(len_recv ==0) return -1;
  352.   return len_recv;
  353. }
  354. int tcp_gethostnamebyip(char *ip, char *host)
  355. {
  356.   struct hostent *hp;
  357.   struct in_addr ul;
  358.   host[0] =0;
  359.   ul.S_un.S_addr =inet_addr(ip);
  360.   if(ul.S_un.S_addr ==0xFFFFFFFF) return -1; // ip error or ip is hostname
  361.   hp =gethostbyaddr((char *)&ul, 4, AF_INET);
  362.   if(hp ==NULL) return -1;  // can not get hostname
  363.   strcpy(host, hp->h_name);
  364.   return 0;
  365. }
  366. int get_local_ip(char *ip)
  367. {
  368.   struct hostent *hp;
  369.   char host[50], *p;
  370.   if(gethostname(host, sizeof(host)) <0) return -1;
  371.   hp =gethostbyname(host);
  372.   if(hp ==NULL) return -1;
  373.   p =(char *)hp->h_addr;
  374.   wsprintf(ip, "%d.%d.%d.%d", (int)p[0]&0xFF, (int)p[1]&0xFF, (int)p[2]&0xFF, (int)p[3]&0xFF);
  375.   return 0;
  376. }
  377. char *get_remote_ip(int sd, char *ip)
  378. {
  379.   struct sockaddr_in addr_in;
  380.   int len =sizeof(addr_in);
  381.   char *p1;
  382.   if(sd <0) return  NULL;
  383.   if(getpeername(sd, (struct sockaddr *)&addr_in, &len) <0)
  384.     return NULL;
  385.   p1 =(char *)&addr_in.sin_addr;
  386.   sprintf(ip, "%d.%d.%d.%d", ((int)p1[0]) &0xff, ((int)p1[1]) &0xff, (int)p1[2] &0xff, (int)p1[3]&0xff);
  387.  
  388.   return ip;
  389. }
  390. unsigned short tcp_htons(unsigned short s)
  391. {
  392.   return htons(s);
  393. }
  394. unsigned short tcp_ntohs(unsigned short s)
  395. {
  396.   return ntohs(s);
  397. }
  398. unsigned long int tcp_htonl(unsigned long int l)
  399. {
  400.   return htonl(l);
  401. }
  402. unsigned long int tcp_ntohl(unsigned long int l)
  403. {
  404.   return ntohl(l);
  405. }
  406. float tcp_htonf(float f)
  407. {
  408.   unsigned char *p, p0, p1;
  409.   if(htons(1) ==1) return f;
  410.   p =(unsigned char *)&f;
  411.   p0 =p[0];
  412.   p1 =p[1];
  413.   p[0] =p[3];
  414.   p[3] =p0;
  415.   p[1] =p[2];
  416.   p[2] =p1;
  417.   return f;
  418. }
  419. float tcp_ntohf(float f)
  420. {
  421.   unsigned char *p, p0, p1;
  422.   if(ntohs(1) ==1) return f;
  423.   p =(unsigned char *)&f;
  424.   p0 =p[0];
  425.   p1 =p[1];
  426.   p[0] =p[3];
  427.   p[3] =p0;
  428.   p[1] =p[2];
  429.   p[2] =p1;
  430.   return f;
  431. }
  432. double tcp_htond(double d)
  433. {
  434.   unsigned char *p, p0, p1, p2, p3;
  435.   if(htons(1) ==1) return d;
  436.   p =(unsigned char *)&d;
  437.   p0 =p[0];
  438.   p1 =p[1];
  439.   p2 =p[2];
  440.   p3 =p[3];
  441.   p[0] =p[7];
  442.   p[7] =p0;
  443.   p[1] =p[6];
  444.   p[6] =p1;
  445.   p[2] =p[5];
  446.   p[5] =p2;
  447.   p[3] =p[4];
  448.   p[4] =p3;
  449.   return d;
  450. }
  451. double tcp_ntohd(double d)
  452. {
  453.   unsigned char *p, p0, p1, p2, p3;
  454.   if(ntohs(1) ==1) return d;
  455.   p =(unsigned char *)&d;
  456.   p0 =p[0];
  457.   p1 =p[1];
  458.   p2 =p[2];
  459.   p3 =p[3];
  460.   p[0] =p[7];
  461.   p[7] =p0;
  462.   p[1] =p[6];
  463.   p[6] =p1;
  464.   p[2] =p[5];
  465.   p[5] =p2;
  466.   p[3] =p[4];
  467.   p[4] =p3;
  468.   return d;
  469. }
  470. unsigned __int64 tcp_htonh(unsigned __int64 d)
  471. {
  472.   unsigned char *p, p0, p1, p2, p3;
  473.   if(htons(1) ==1) return d;
  474.   p =(unsigned char *)&d;
  475.   p0 =p[0];
  476.   p1 =p[1];
  477.   p2 =p[2];
  478.   p3 =p[3];
  479.   p[0] =p[7];
  480.   p[7] =p0;
  481.   p[1] =p[6];
  482.   p[6] =p1;
  483.   p[2] =p[5];
  484.   p[5] =p2;
  485.   p[3] =p[4];
  486.   p[4] =p3;
  487.   return d;
  488. }
  489. unsigned __int64 tcp_ntohh(unsigned __int64 d)
  490. {
  491.   unsigned char *p, p0, p1, p2, p3;
  492.   if(ntohs(1) ==1) return d;
  493.   p =(unsigned char *)&d;
  494.   p0 =p[0];
  495.   p1 =p[1];
  496.   p2 =p[2];
  497.   p3 =p[3];
  498.   p[0] =p[7];
  499.   p[7] =p0;
  500.   p[1] =p[6];
  501.   p[6] =p1;
  502.   p[2] =p[5];
  503.   p[5] =p2;
  504.   p[3] =p[4];
  505.   p[4] =p3;
  506.   return d;
  507. }
  508. void peek_message(void)
  509. {
  510.   MSG msg;
  511.   if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
  512.   {
  513.     TranslateMessage(&msg);
  514.     DispatchMessage(&msg);
  515.   }
  516. }