tcp.cpp
上传用户:adsacym
上传日期:2007-01-07
资源大小:67k
文件大小:10k
源码类别:

Internet/IE编程

开发平台:

Visual C++

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