非阻塞模式(ioctlsocket)
//Server.cpp
#include <stdio.h>
#include <winsock2.h> //winsock.h (2种套接字版本)
#pragma comment(lib,"ws2_32.lib") //wsock32.lib #define MAXSIZE 100 // int main()
{
//
int retVal; char buf[MAXSIZE]; //初始化套接字库
WORD wVersionRequest;
WSADATA wsadata; wVersionRequest=MAKEWORD(,); retVal=WSAStartup(wVersionRequest,&wsadata);
if(retVal == SOCKET_ERROR)
{
printf("WSAStartup failed!"); return -;
} //创建套接字
SOCKET sServer;
sServer=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(sServer == INVALID_SOCKET)
{
printf("socket failed!"); WSACleanup();
return -; //每次检测到失败后,即需要返回
} //设置为非阻塞模式
int imode=;
retVal=ioctlsocket(sServer,FIONBIO,(u_long *)&imode);
if(retVal == SOCKET_ERROR)
{
printf("ioctlsocket failed!"); closesocket(sServer);
WSACleanup();
return -;
} //绑定套接字并将其设置为监听状态
SOCKADDR_IN addrServ;
addrServ.sin_family=AF_INET;
addrServ.sin_port =htons();
addrServ.sin_addr.S_un.S_addr=inet_addr("192.168.0.102"); retVal=bind(sServer,(SOCKADDR *)&addrServ,sizeof(addrServ)); //绑定套接字到某一个具体的服务器
if(retVal == SOCKET_ERROR)
{
printf("bind failed!"); closesocket(sServer);
WSACleanup();
return -;
} retVal=listen(sServer,); //第二个参数,表示最大连接数目
if(retVal == SOCKET_ERROR)
{
printf("listen failed!"); closesocket(sServer);
WSACleanup();
return -;
} //接受连接
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) //表示没有客户端发起连接,继续循环
{
Sleep();
continue;
}
else
{
printf("accept failed!"); closesocket(sServer); //连接失败,关闭服务器套接字并释放套接字库
WSACleanup(); //
return -;
}
} break; //
} //接收数据
while(true)
{
retVal=recv(sClient,buf,strlen(buf),);
if(retVal == SOCKET_ERROR)
{
errcode=WSAGetLastError(); //这个变量errcode没有重复定义吗?
if(errcode == WSAEWOULDBLOCK) //
{
Sleep();
continue;
}
else
{
if(errcode==WSAETIMEDOUT || errcode==WSAENETDOWN)
{
closesocket(sClient);
closesocket(sServer);
WSACleanup();
return -;
}
}
} if(buf == "quit") //如果接收数据为"quit",则发送回显"quit"
{
retVal=send(sClient,buf,strlen(buf),);
break;
}
else
{
//发送数据
while(true)
{
retVal=send(sClient,buf,strlen(buf),); //a.回显接收数据;b.第四个参数:0?
if(retVal == SOCKET_ERROR) //错误处理
{
errcode=WSAGetLastError();
if(errcode == WSAEWOULDBLOCK) //
{
Sleep();
continue;
}
else
{
closesocket(sClient);
closesocket(sServer);
WSACleanup();
return -; }
} break; //如果发送数据成功,则退出循环
} }
} }
//Client.cpp
#include <stdio.h>
#include <WinSock2.h> //winsock.h
#pragma comment(lib,"ws2_32.lib"); //wsock32.lib #include <iostream>
using namespace std; #include <string.h> //strcpy函数 #define MAXSIZE 100 // int main()
{
//
int retVal; char buf[MAXSIZE]; //初始化套接字库
WORD wVersionRequest;
WSADATA wsadata; wVersionRequest=MAKEWORD(,); retVal=WSAStartup(wVersionRequest,&wsadata);
if(retVal == SOCKET_ERROR)
{
printf("WSAStartup failed!"); return -;
} //创建套接字
SOCKET sClient;
sClient=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(sClient == INVALID_SOCKET)
{
printf("socket failed!"); WSACleanup();
return -; //每次检测到失败后,即需要返回
} //设置为非阻塞模式
int imode=;
retVal=ioctlsocket(sClient,FIONBIO,(u_long *)&imode);
if(retVal == SOCKET_ERROR)
{
printf("ioctlsocket failed!"); closesocket(sClient);
WSACleanup();
return -;
} //发起连接
sockaddr_in addrServ;
addrServ.sin_family=AF_INET; //表示使用的是,TCP/IP地址家族
addrServ.sin_port =htons(); //为什么要使用htons宏?
addrServ.sin_addr.S_un.S_addr=inet_addr("192.168.0.102"); int len=sizeof(sockaddr_in); //sizeof只是一个运算符,不是函数 while(true)
{
retVal=connect(sClient,(sockaddr *)&addrServ,len); //连接到某一个具体的服务器
if(retVal == INVALID_SOCKET)
{
int errcode=WSAGetLastError();
if(errcode==WSAEWOULDBLOCK || errcode==WSAEINVAL) //表示服务器端未准备好,继续循环
{
Sleep();
continue;
}
else
{
if(errcode == WSAEISCONN) //连接成功,则退出
{
break;
}
else //否则连接失败,关闭客户端套接字并释放套接字库
{
printf("connect failed!"); closesocket(sClient);
WSACleanup(); //
return -;
}
}
} } //发送数据
while(true)
{
//
//scanf(buf);
//cin>>buf; strcpy(buf,"Hello TCP!"); retVal=send(sClient,buf,strlen(buf),); //a.回显接收数据;b.第四个参数:0?
if(retVal == SOCKET_ERROR) //错误处理
{
int errcode=WSAGetLastError();
if(errcode == WSAEWOULDBLOCK) //
{
Sleep();
continue;
}
else
{
printf("send failed!"); closesocket(sClient);
//closesocket(sServer);
WSACleanup();
return -; }
} break; //如果发送数据成功,则退出循环
} //接收数据
while(true)
{
retVal=recv(sClient,buf,strlen(buf),);
if(retVal == SOCKET_ERROR)
{
int errcode=WSAGetLastError(); //这个变量errcode没有重复定义吗?
if(errcode == WSAEWOULDBLOCK) //
{
Sleep();
continue;
}
else
{
if(errcode==WSAETIMEDOUT || errcode==WSAENETDOWN)
{
printf("recv failed!"); closesocket(sClient);
//closesocket(sServer);
WSACleanup();
return -;
}
}
} break;
}
}
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
非阻塞模式(ioctlsocket)的更多相关文章
- Socket 阻塞模式和非阻塞模式
阻塞I/O模型: 简介:进程会一直阻塞,直到数据拷贝 完成 应用程序调用一个IO函数,导致应用程序阻塞,等待数据准备好. 如果数据没有准备好,一直等待….数据准备好了,从内核拷贝到用户空间,IO函数返 ...
- 看到关于socket非阻塞模式设置方式记录一下。
关于socket的阻塞与非阻塞模式以及它们之间的优缺点,这已经没什么可言的:我打个很简单的比方,如果你调用socket send函数时: 如果是阻塞模式下: send先比较待发送数据的长度len和套接 ...
- 服务器编程心得(四)—— 如何将socket设置为非阻塞模式
1. windows平台上无论利用socket()函数还是WSASocket()函数创建的socket都是阻塞模式的: SOCKET WSAAPI socket( _In_ int af, _In_ ...
- PHP非阻塞模式 (转自 尘缘)
让PHP不再阻塞当PHP作为后端处理需要完成一些长时间处理,为了快速响应页面请求,不作结果返回判断的情况下,可以有如下措施: 一.若你使用的是FastCGI模式,使用fastcgi_finish_re ...
- TCP同步与异步及阻塞模式,多线程+阻塞模式,非阻塞模式简单介绍
首先我简单介绍一下同步TCP编程 与异步TCP编程. 在服务端我们通常用一个TcpListener来监听一个IP和端口.客户端来一个请求的连接,在服务端可以用同步的方式来接收,也可以用异步的方式去接收 ...
- UDP socket 设置为的非阻塞模式
UDP socket 设置为的非阻塞模式 Len = recvfrom(SocketFD, szRecvBuf, sizeof(szRecvBuf), MSG_DONTWAIT, (struct so ...
- socket异步通信-如何设置成非阻塞模式、非阻塞模式下判断connect成功(失败)、判断recv/recvfrom成功(失败)、判断send/sendto
socket异步通信-如何设置成非阻塞模式.非阻塞模式下判断connect成功(失败).判断recv/recvfrom成功(失败).判断send/sendto 博客分类: Linux Socket s ...
- 转:PHP非阻塞模式
你可以任意转摘“PHP非阻塞模式”,但请保留本文出处和版权信息.作者:尘缘,QQ:130775,来源:http://www.4wei.cn/archives/1002336 让PHP不再阻塞当PHP作 ...
- 转:PHP中实现非阻塞模式
原文来自于:http://blog.csdn.net/linvo/article/details/5466046 程序非阻塞模式,这里也可以理解成并发.而并发又暂且可以分为网络请求并发 和本地并发 . ...
随机推荐
- 【003:使用SW4STM32不进入中断的原因】
系统环境: ubuntu 16.04 64bit开发环境:SW4STM32记录时间: 2017年07月01日联系方式: yexiaopeng1992@126.com背景: 在ubuntu下使用ST官方 ...
- 理解linux网络管理命令
linux 管理命令,iproute 查看帮助文件: man ip 以下为常用帮助文件. SEE ALSO ip-address(), ip-addrlabel(), ip-l2tp(), ip-li ...
- django的url反向解析
目的:防止页面中url地址改变,其他与这个URL地址有关联的都要改,减少耦合度 使用:主要分为在html中和视图函数中的使用 HTML中的使用: 如果我们在项目的url文件中通过include导入了应 ...
- 淘宝客订单api处理优化
首选我们看看api定义: http://open.taobao.com/api.htm?docId=38078&docType=2&scopeId=14474 注意下span这个参数 ...
- Python批量合并处理B站视频
最近想学习后端,又不想花钱,怎么办呢?于是在手机端B站(哔哩哔哩)上面找到了满意的免费视频教程,但是手机端看起来很不方便啊.于是,我通过在手机端缓存下来后,导入到了电脑端,但是我后面了发现两个问题: ...
- excel VBA动态链接数据库
最近车间制造部有需求,需要通过excel填写的ID获取数据库中的某个取值.研究了一下VBA,简要记录一下代码,仅供参考. Function GETPMAX(SID As String) As Stri ...
- hadoop过程中遇到的错误与解决方法
本文整理了在hadoop学习过程中遇到的各种问题. windows下开发环境搭建 大部分情况下,我们都是在windows下开发,hadoop则一般部署于linux服务器(无论是CDH还是原生hadoo ...
- archer docker安装部署
1.准备配置文件从archer项目官网下载/archer/settings.py文件,根据自己情况放到相应的目录我下载后放到如下目录[root@lenovo opt]# mkdir -p /opt/a ...
- HDOJ1312 Red and black(DFS深度优先搜索)
There is a rectangular room, covered with square tiles. Each tile is colored either red or black. A ...
- Labels & Codes
Labels & Codes List of Codes Adjectives Nouns Verbs Other labels Adjectives adjective A word th ...