非阻塞模式(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

posted @ 2014-08-19 23:30  _**  阅读(9366)  评论(0编辑  收藏  举报