• 非阻塞模式(ioctlsocket)


      1     //Server.cpp  
      2     #include <stdio.h>  
      3     #include <winsock2.h>             //winsock.h (2种套接字版本)  
      4     #pragma comment(lib,"ws2_32.lib") //wsock32.lib  
      5      
      6     #define MAXSIZE 100 //  
      7      
      8     int main()  
      9     {  
     10         //  
     11         int retVal;  
     12      
     13         char buf[MAXSIZE];  
     14      
     15         //初始化套接字库  
     16         WORD wVersionRequest;  
     17         WSADATA wsadata;  
     18      
     19         wVersionRequest=MAKEWORD(2,2);  
     20      
     21         retVal=WSAStartup(wVersionRequest,&wsadata);  
     22         if(retVal == SOCKET_ERROR)  
     23         {  
     24             printf("WSAStartup failed!");  
     25      
     26             return -1;  
     27         }  
     28      
     29         //创建套接字  
     30         SOCKET sServer;  
     31         sServer=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);  
     32         if(sServer == INVALID_SOCKET)  
     33         {  
     34             printf("socket failed!");  
     35      
     36             WSACleanup();  
     37             return -1; //每次检测到失败后,即需要返回  
     38         }  
     39      
     40         //设置为非阻塞模式  
     41         int imode=1;  
     42         retVal=ioctlsocket(sServer,FIONBIO,(u_long *)&imode);  
     43         if(retVal == SOCKET_ERROR)  
     44         {  
     45             printf("ioctlsocket failed!");  
     46      
     47             closesocket(sServer);  
     48             WSACleanup();  
     49             return -1;  
     50         }  
     51      
     52         //绑定套接字并将其设置为监听状态  
     53         SOCKADDR_IN addrServ;  
     54         addrServ.sin_family=AF_INET;  
     55         addrServ.sin_port  =htons(5000);  
     56         addrServ.sin_addr.S_un.S_addr=inet_addr("192.168.0.102");  
     57      
     58         retVal=bind(sServer,(SOCKADDR *)&addrServ,sizeof(addrServ)); //绑定套接字到某一个具体的服务器  
     59         if(retVal == SOCKET_ERROR)  
     60         {  
     61             printf("bind failed!");  
     62      
     63             closesocket(sServer);  
     64             WSACleanup();  
     65             return -1;  
     66         }  
     67      
     68         retVal=listen(sServer,1); //第二个参数,表示最大连接数目  
     69         if(retVal == SOCKET_ERROR)  
     70         {  
     71             printf("listen failed!");  
     72      
     73             closesocket(sServer);  
     74             WSACleanup();  
     75             return -1;  
     76         }  
     77      
     78      
     79         //接受连接  
     80         sockaddr_in addrClient; //定义一个临时地址,用于接受连接(注意:某个客户端由Client.cpp确定)  
     81         int len=sizeof(sockaddr_in);  
     82      
     83         SOCKET sClient;  
     84         int errcode;  
     85      
     86         while(true)  
     87         {  
     88             sClient=accept(sServer,(sockaddr *)&addrClient,&len);  
     89             if(sClient == INVALID_SOCKET)  
     90             {  
     91                 errcode=WSAGetLastError();  
     92                 if(errcode == WSAEWOULDBLOCK)  //表示没有客户端发起连接,继续循环  
     93                 {  
     94                     Sleep(100);  
     95                     continue;  
     96                 }  
     97                 else 
     98                 {  
     99                     printf("accept failed!");  
    100      
    101                     closesocket(sServer); //连接失败,关闭服务器套接字并释放套接字库  
    102                     WSACleanup(); //  
    103                     return -1;  
    104                 }  
    105             }  
    106      
    107             break; //  
    108         }  
    109      
    110         //接收数据  
    111         while(true)  
    112         {  
    113             retVal=recv(sClient,buf,strlen(buf),0);  
    114             if(retVal == SOCKET_ERROR)  
    115             {  
    116                 errcode=WSAGetLastError(); //这个变量errcode没有重复定义吗?  
    117                 if(errcode == WSAEWOULDBLOCK)  //  
    118                 {  
    119                     Sleep(100);  
    120                     continue;  
    121                 }  
    122                 else 
    123                 {  
    124                     if(errcode==WSAETIMEDOUT || errcode==WSAENETDOWN)  
    125                     {  
    126                         closesocket(sClient);  
    127                         closesocket(sServer);  
    128                         WSACleanup();  
    129                         return -1;  
    130                     }  
    131                 }  
    132             }  
    133      
    134             if(buf == "quit") //如果接收数据为"quit",则发送回显"quit"  
    135             {  
    136                 retVal=send(sClient,buf,strlen(buf),0);  
    137                 break;  
    138             }  
    139             else 
    140             {  
    141                 //发送数据  
    142                 while(true)  
    143                 {  
    144                     retVal=send(sClient,buf,strlen(buf),0); //a.回显接收数据;b.第四个参数:0?  
    145                     if(retVal == SOCKET_ERROR)  //错误处理  
    146                     {  
    147                         errcode=WSAGetLastError();  
    148                         if(errcode == WSAEWOULDBLOCK)  //  
    149                         {  
    150                             Sleep(100);  
    151                             continue;  
    152                         }  
    153                         else 
    154                         {  
    155                             closesocket(sClient);  
    156                             closesocket(sServer);  
    157                             WSACleanup();  
    158                             return -1;  
    159      
    160                         }  
    161                     }  
    162      
    163                     break; //如果发送数据成功,则退出循环  
    164                 }  
    165      
    166             }  
    167         }  
    168      
    169     } 
      1     //Client.cpp  
      2     #include <stdio.h>  
      3     #include <WinSock2.h> //winsock.h  
      4     #pragma comment(lib,"ws2_32.lib"); //wsock32.lib  
      5      
      6     #include <iostream>  
      7     using namespace std;  
      8      
      9     #include <string.h> //strcpy函数  
     10      
     11     #define MAXSIZE 100 //  
     12      
     13     int main()  
     14     {  
     15         //  
     16         int retVal;  
     17      
     18         char buf[MAXSIZE];  
     19      
     20         //初始化套接字库  
     21         WORD wVersionRequest;  
     22         WSADATA wsadata;  
     23      
     24         wVersionRequest=MAKEWORD(2,2);  
     25      
     26         retVal=WSAStartup(wVersionRequest,&wsadata);  
     27         if(retVal == SOCKET_ERROR)  
     28         {  
     29             printf("WSAStartup failed!");  
     30      
     31             return -1;  
     32         }  
     33      
     34         //创建套接字  
     35         SOCKET sClient;  
     36         sClient=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);  
     37         if(sClient == INVALID_SOCKET)  
     38         {  
     39             printf("socket failed!");  
     40      
     41             WSACleanup();  
     42             return -1; //每次检测到失败后,即需要返回  
     43         }  
     44      
     45         //设置为非阻塞模式  
     46         int imode=1;  
     47         retVal=ioctlsocket(sClient,FIONBIO,(u_long *)&imode);  
     48         if(retVal == SOCKET_ERROR)  
     49         {  
     50             printf("ioctlsocket failed!");  
     51      
     52             closesocket(sClient);  
     53             WSACleanup();  
     54             return -1;  
     55         }  
     56      
     57      
     58         //发起连接  
     59         sockaddr_in addrServ;  
     60         addrServ.sin_family=AF_INET; //表示使用的是,TCP/IP地址家族  
     61         addrServ.sin_port  =htons(5000); //为什么要使用htons宏?  
     62         addrServ.sin_addr.S_un.S_addr=inet_addr("192.168.0.102");  
     63      
     64         int len=sizeof(sockaddr_in); //sizeof只是一个运算符,不是函数  
     65      
     66         while(true)  
     67         {  
     68             retVal=connect(sClient,(sockaddr *)&addrServ,len); //连接到某一个具体的服务器  
     69             if(retVal == INVALID_SOCKET)  
     70             {  
     71                 int errcode=WSAGetLastError();  
     72                 if(errcode==WSAEWOULDBLOCK || errcode==WSAEINVAL)  //表示服务器端未准备好,继续循环  
     73                 {  
     74                     Sleep(100);  
     75                     continue;  
     76                 }  
     77                 else 
     78                 {  
     79                     if(errcode == WSAEISCONN) //连接成功,则退出  
     80                     {  
     81                         break;   
     82                     }  
     83                     else                      //否则连接失败,关闭客户端套接字并释放套接字库  
     84                     {  
     85                         printf("connect failed!");  
     86      
     87                         closesocket(sClient);   
     88                         WSACleanup(); //  
     89                         return -1;  
     90                     }  
     91                  }  
     92             }  
     93      
     94         }  
     95      
     96         //发送数据  
     97         while(true)  
     98         {  
     99             //  
    100             //scanf(buf);  
    101             //cin>>buf;  
    102      
    103             strcpy(buf,"Hello TCP!");  
    104      
    105             retVal=send(sClient,buf,strlen(buf),0); //a.回显接收数据;b.第四个参数:0?  
    106             if(retVal == SOCKET_ERROR)  //错误处理  
    107             {  
    108                 int errcode=WSAGetLastError();  
    109                 if(errcode == WSAEWOULDBLOCK)  //  
    110                 {  
    111                     Sleep(100);  
    112                     continue;  
    113                 }  
    114                 else 
    115                 {  
    116                     printf("send failed!");  
    117      
    118                     closesocket(sClient);  
    119                     //closesocket(sServer);  
    120                     WSACleanup();  
    121                     return -1;  
    122      
    123                 }  
    124             }  
    125      
    126             break; //如果发送数据成功,则退出循环  
    127         }  
    128      
    129         //接收数据  
    130         while(true)  
    131         {  
    132             retVal=recv(sClient,buf,strlen(buf),0);  
    133             if(retVal == SOCKET_ERROR)  
    134             {  
    135                 int errcode=WSAGetLastError(); //这个变量errcode没有重复定义吗?  
    136                 if(errcode == WSAEWOULDBLOCK)  //  
    137                 {  
    138                     Sleep(100);  
    139                     continue;  
    140                 }  
    141                 else 
    142                 {  
    143                     if(errcode==WSAETIMEDOUT || errcode==WSAENETDOWN)  
    144                     {  
    145                         printf("recv failed!");  
    146      
    147                         closesocket(sClient);  
    148                         //closesocket(sServer);  
    149                         WSACleanup();  
    150                         return -1;  
    151                     }  
    152                 }  
    153             }  
    154      
    155             break;  
    156         }  
    157     } 

    1.

    #include <winsock2.h>             //winsock.h (2种套接字版本)
    #pragma comment(lib,"ws2_32.lib") //wsock32.lib

    2.

    retVal=ioctlsocket(sServer,FIONBIO,(u_long *)&imode); //第3个参数通常设为1(同时第2个参数设为FIONBIO),表示非阻塞模式

    3.

    a. //绑定套接字并将其设置为监听状态
     SOCKADDR_IN addrServ;
     addrServ.sin_family=AF_INET;
     addrServ.sin_port  =htons(5000);
     addrServ.sin_addr.S_un.S_addr=inet_addr("192.168.0.102");

     retVal=bind(sServer,(SOCKADDR *)&addrServ,sizeof(addrServ)); //绑定套接字到某一个具体的服务器

    这一段代码表明,bind函数需要定义一个addrServ,并且要为每个字段赋值。

    b. retVal=listen(sServer,1); //第二个参数,表示最大连接数目

    4.

    //接受连接
     sockaddr_in addrClient; //定义一个临时地址,用于接受连接(注意:某个客户端由Client.cpp确定)
     int len=sizeof(sockaddr_in);

     SOCKET sClient;
     int errcode;

     while(true)
     {
      sClient=accept(sServer,(sockaddr *)&addrClient,&len);
      if(sClient == INVALID_SOCKET)
      {
       errcode=WSAGetLastError();
       if(errcode == WSAEWOULDBLOCK)  //表示没有客户端发起连接,继续循环
       {

    ……

    5.

    retVal=recv(sClient,buf,strlen(buf),0);//第4个参数,表示影响该函数的行为(通常设为0)

    retVal=send(sClient,buf,strlen(buf),0); //a.回显接收数据;b.第四个参数:0?

    ------------------------------------------------------------------------------------------------

    1.

    addrServ.sin_port  =htons(5000); //为什么要使用htons宏?前者的字段类型和宏的返回值类型一致
     addrServ.sin_addr.S_un.S_addr=inet_addr("192.168.0.102"); //同理,后者函数的返回值类型和字段类型一致

    2.
      //scanf(buf); //问题①:为何这两个发送字符串我发送不了?
      //cin>>buf;

      strcpy(buf,"Hello TCP!"); //发送固定字符串

    3.

    问题②:下次继续做实验,bind failed的原因,而且是Client.cpp端出现的 真奇怪?(自己有调试,结果发现port字段和自己设置的不一致,不知为何)

    http://qxzbgzh.blog.51cto.com/blog/2821013/875991

  • 相关阅读:
    【解压缩命令】 -费元星
    【虚拟机取得该虚拟机的所有权失败】--费元星
    solr 常见的问题整理 -费元星
    oracle 建立一个视图,然后授权其他用户访问
    虚拟机安装win7 64位-完美解决-费元星
    solr 学习
    CentOS安装JDK1.7
    Nginx+Tomcat多站点访问默认主页问题-狒狒完美解决-Q9715234
    pip 安装时提示uvloop/loop.c:20:10: fatal error: Python.h解决
    MySQL锁总结
  • 原文地址:https://www.cnblogs.com/Fightingbirds/p/3923539.html
Copyright © 2020-2023  润新知