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

Ftp客户端

开发平台:

Visual C++

  1. #include <windows.h>
  2. #include <winsock.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <time.h>
  6. #include "tcp.h"
  7. int sd_connect =-1, sd_bind =-1, sd_accept =-1;
  8. int wsa_ok =0;
  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(sd_connect >=0) closesocket(sd_connect);
  21.   if(sd_accept >=0) closesocket(sd_accept);
  22.   if(sd_bind >=0) closesocket(sd_bind);
  23.   if(wsa_ok) WSACleanup();
  24.   sd_connect =sd_accept =sd_bind =-1;
  25.   return 0;
  26. }
  27. int tcp_status(int  sd, char *type, int timeout)
  28. {
  29.   fd_set rset, wset, eset;
  30.   fd_set FAR *prset =NULL, *pwset =NULL, *peset =NULL;
  31.   struct timeval tval;
  32.   int i, status, err_no =0;
  33.   time_t t1, t2;
  34.   MSG msg;
  35.   tval.tv_sec =0;
  36.   tval.tv_usec =0;
  37.   time(&t1);
  38.   t2 =t1;
  39.   while(t2-t1 < timeout)
  40.   {
  41.     FD_ZERO(&rset);
  42.     FD_ZERO(&wset);
  43.     FD_ZERO(&eset);
  44.     for(i =0; i<(int)strlen(type); i++)
  45.     {
  46.       if(type[i] =='r') { FD_SET(sd, &rset); prset =&rset; }
  47.       if(type[i] =='w') { FD_SET(sd, &wset); pwset =&wset; }
  48.       if(type[i] =='e') { FD_SET(sd, &eset); peset =&eset; }
  49.     }
  50.     status =select(sd+1, prset, pwset, peset, &tval);
  51.     time(&t2);
  52.     if(status ==0)
  53.     {
  54.       if(PeekMessage(&msg, 0, NULL, NULL, PM_REMOVE))
  55.       {
  56.         TranslateMessage(&msg);
  57.         DispatchMessage(&msg);
  58.         if(msg.message ==WM_QUIT) return -1;
  59.       }
  60.       if(t2-t1 <timeout) continue;
  61.       else
  62.       {
  63.         if(prset) FD_CLR((UINT)sd,&rset);
  64.         if(pwset) FD_CLR((UINT)sd,&wset);
  65.         if(peset) FD_CLR((UINT)sd,&eset);
  66.         SetLastError(WSAETIMEDOUT);
  67.         return -10;
  68.       }
  69.     }
  70.     if(peset && FD_ISSET(sd, peset))
  71.     {
  72.       if(prset !=NULL) FD_CLR((UINT)sd,&rset);
  73.       if(pwset !=NULL) FD_CLR((UINT)sd,&wset);
  74.       if(peset !=NULL) FD_CLR((UINT)sd,&eset);
  75.       err_no =WSAGetLastError();
  76.       /*
  77.       len =sizeof(errno);
  78.       getsockopt(sd, SOL_SOCKET, SO_ERROR, (char *)&errno, &len);
  79.       */
  80.       return -1;
  81.     }
  82.     if((prset && FD_ISSET(sd, prset)) || (pwset && FD_ISSET(sd, pwset)))
  83.     {
  84.       err_no =WSAGetLastError();
  85.       /*
  86.       len =sizeof(errno);
  87.       getsockopt(sd, SOL_SOCKET, SO_ERROR, (char *)&errno, &len);
  88.       */
  89.     }
  90.     if(prset !=NULL) FD_CLR((UINT)sd,&rset);
  91.     if(pwset !=NULL) FD_CLR((UINT)sd,&wset);
  92.     if(peset !=NULL) FD_CLR((UINT)sd,&eset);
  93.     if(status <0)
  94.       err_no =WSAGetLastError();
  95.     if(err_no ==WSAEINTR) return WSAEINTR;
  96.     if(err_no)
  97.     {
  98.       return -1;
  99.     }
  100.     else break;
  101.   }
  102.   return 0;
  103. }
  104. int tcp_bind(HWND hWnd, int port)
  105. {
  106. struct sockaddr_in addr;
  107.     char temp[200];
  108.     int sd;
  109.     sd =-1;
  110. if((sd =socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) <0)
  111. {
  112. sprintf(temp, "socket failed! errno:%d", WSAGetLastError());
  113. return -1;
  114. }
  115. memset(&addr, 0, sizeof(addr));
  116. addr.sin_family =AF_INET;
  117. addr.sin_port =htons((unsigned short)port);
  118.     int l =1;
  119.     setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, (char *)&l, sizeof(l));
  120.     /*setsockopt(sd, SOL_SOCKET, SO_REUSEPORT, (char *)&l, sizeof(l));*/
  121. if(bind(sd, (struct sockaddr *)&addr, sizeof(addr)) <0)
  122. {
  123.       sprintf(temp, "bind failed! errno:%d", WSAGetLastError());
  124.   closesocket(sd);
  125.       return -1;
  126. }
  127. if(hWnd && WSAAsyncSelect(sd, hWnd, WM_TCP, FD_ACCEPT) !=0)
  128.     {
  129.       sprintf(temp, "tcp_bind:WSAAsyncSelect failed!");
  130.       closesocket(sd);
  131.       return -2;
  132.     }
  133.     sd_bind =sd;
  134.     listen(sd_bind, 5);
  135.     return sd;
  136. }
  137. int tcp_accept(int sd, int timeout)
  138. {
  139.   int sd_acc =-1;
  140.   struct sockaddr_in sa;
  141.   int len;
  142.   /*unsigned long l;*/
  143.   if(tcp_status(sd, "rw", timeout) <0)
  144.     return -1;
  145.   len =sizeof(sa);
  146.   if((sd_acc =accept(sd, (struct sockaddr *)&sa, &len)) <0)
  147.     return -1;
  148.   sd_accept =sd_acc;
  149.   /*  l =1;
  150.     if(ioctlsocket(sd_acc, FIONBIO, &l) <0)
  151.     {
  152.       closesocket(sd);
  153.       return -1;
  154.     }*/
  155.   return sd_acc;
  156. }
  157. int tcp_connect(char *hostname, int port, int timeout)
  158. {
  159. struct hostent *hp;
  160. struct sockaddr_in addr;
  161.     char temp[200];
  162.     unsigned long ul;
  163.     long l;
  164.     int sd =-1;
  165.     sd =-1;
  166. if((sd =socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) <0)
  167. {
  168. sprintf(temp, "socket failed! errno:%d", WSAGetLastError());
  169. return -1;
  170. }
  171. memset(&addr, 0, sizeof(addr));
  172.     ul =inet_addr(hostname);
  173.     if(ul ==0xffffffff)
  174.     {
  175.   if((hp =gethostbyname(hostname)) ==NULL)
  176.   {
  177.         sprintf(temp, "gethostbyname and inet_addr failed! errno:%d", WSAGetLastError());
  178.     closesocket(sd);
  179.         return -1;
  180.       }
  181.   memcpy(&addr.sin_addr, hp->h_addr, hp->h_length);
  182. }
  183.     else  addr.sin_addr.s_addr=ul;
  184. addr.sin_family =AF_INET;
  185. addr.sin_port =htons((unsigned short)port);
  186.     l =1;
  187.     /*if(ioctlsocket(sd, FIONBIO, (unsigned long *)&l) <0)
  188.     {
  189.       closesocket(sd);
  190.       return -1;
  191.     }*/
  192.     if(setsockopt(sd, IPPROTO_TCP, TCP_NODELAY, (char *)&l, sizeof(l)) <0)
  193.     {
  194.       closesocket(sd);
  195.       return -1;
  196.     }
  197.     while(connect(sd, (struct sockaddr *)&addr, sizeof(addr)) !=0)
  198.     {
  199.       int err_no =WSAGetLastError();
  200.       if(err_no ==WSAEINTR) continue;
  201.   if(err_no ==WSAEINPROGRESS) break;
  202.       sprintf(temp, "connect:连接服务器失败!n检查服务器端程序是否运行n且主机地址是否%s, 端口是否%dn errno=%d",
  203.               hostname, port, err_no);
  204.       closesocket(sd);
  205.   return -1;
  206. }
  207.     if(tcp_status(sd, "w", timeout) <0)
  208.     {
  209.       sprintf(temp, "status:连接服务器失败!n检查服务器端程序是否运行n且主机地址是否%s, 端口是否%dn"
  210.                     "errno=%d",
  211.             hostname, port, WSAGetLastError());
  212.       closesocket(sd);
  213.       return -1;
  214.     }
  215.     sd_connect =sd;
  216.     return sd;
  217. }
  218. void tcp_close(int sd)
  219. {
  220. tcp_disconnect(sd);
  221. }
  222. void tcp_disconnect(int sd)
  223. {
  224.   if(sd >0)
  225.   {
  226.     closesocket(sd);
  227.     if(sd ==sd_connect) sd_connect =-1;
  228.     if(sd ==sd_accept) sd_accept =-1;
  229. if(sd ==sd_bind) sd_bind =-1;
  230.   }
  231. }
  232. int tcp_send(int sd, char *buf, int len, int timeout)
  233. {
  234.   int len1, len_send =0;
  235.   time_t t1, t2;
  236.   len_send =0;
  237.   time(&t1);
  238.   t2 =t1;
  239.   while(len_send <len)
  240.   {
  241.     if(t2-t1 >timeout)
  242.       return len_send;
  243.     if(tcp_status(sd, "w", timeout-(t2-t1)) <0)
  244.       return len_send;
  245.     if((len1 =send(sd, &buf[len_send], len-len_send, 0)) <=0)
  246.     {
  247.       /*if(GetLastError() ==WSAEWOULDBLOCK)
  248.       {
  249.         time(&t2);
  250.         continue;
  251.       }*/
  252.       return len_send;
  253.     }
  254.     len_send +=len1;
  255.     time(&t2);
  256.   }
  257.   return len_send;
  258. }
  259. int tcp_recv(int sd, char *buf, int len, int timeout)
  260. {
  261.   int len1, len_recv;
  262.   time_t t2, t1;
  263.   len_recv =0;
  264.   time(&t1);
  265.   t2 =t1;
  266.   while(len_recv <len)
  267.   {
  268.     if(t2 -t1 >timeout)
  269.       return len_recv;
  270.     if(tcp_status(sd, "r", timeout-(t2-t1)) <0)
  271.       return len_recv;
  272.      if((len1 =recv(sd, &buf[len_recv], len-len_recv, 0)) <=0)
  273.      {
  274.        /*if(timeout ==0) break;
  275.        if(GetLastError() ==WSAEWOULDBLOCK)
  276.        {
  277.          time(&t2);
  278.          continue;
  279.        }*/
  280.        return len_recv;
  281.     }
  282.     len_recv +=len1;
  283.     time(&t2);
  284.   }
  285.   return len_recv;
  286. }