看到关于socket非阻塞模式设置方式记录一下。
2014-06-23 16:23
169 查看
关于socket的阻塞与非阻塞模式以及它们之间的优缺点,这已经没什么可言的;我打个很简单的比方,如果你调用socket send函数时;
如果是阻塞模式下:
send先比较待发送数据的长度len和套接字s的发送缓冲的长度,如果len大于s的发送缓冲区的长度,该函数返回SOCKET_ERROR;如果len小于或者等于s的发送缓冲区的长度,那么send先检查协议是否正在发送s的发送缓冲中的数据,如果是就等待协议把数据发送完,如果协议还没有开始发送s的发送缓冲中的数据或者s的发送缓冲中没有数据,那么 send就比较s的发送缓冲区的剩余空间和len,如果len大于剩余空间大小,send就一直等待协议把s的发送缓冲中的数据发送完,如果len小于剩余空间大小send就仅仅把buf中的数据copy到剩余空间里
如果是非阻塞模式下:
在调用socket send函数时,如果能写到socket缓冲区时,就写数据并返回实际写的字节数目,当然这个返回的实际值可能比你所要写的数据长度要小些(On nonblocking stream oriented sockets, the number of bytes written can be between 1 and the requested length, depending on buffer availability on both the client and server computers),如果不可写的话,就直接返回SOCKET_ERROR了,所以没有等待的过程。。
经过上面的介绍后,下面介绍如何设置socket的非阻塞模式:
当使用socket()函数和WSASocket()函数创建套接字时,默认都是阻塞的。在创建套接字之后,通过调用ioctlsocket()函数,将该套接字设置为非阻塞模式。
//-------------------------
// Set the socket I/O mode: In this case FIONBIO
// enables or disables the blocking mode for the
// socket based on the numerical value of iMode.
// If iMode = 0, blocking is enabled;
// If iMode != 0, non-blocking mode is enabled.
u_long iMode = 1; //non-blocking mode is enabled.
ioctlsocket(m_socket, FIONBIO, &iMode); //设置为非阻塞模式
套接字设置为非阻塞模式后,在调用Windows Sockets API函数时,调用函数会立即返回。大多数情况下,这些函数调用都会调用“失败”,并返回WSAEWOULDBLOCK错误代码。说明请求的操作在调用期间内没有时间完成。通常,应用程序需要重复调用该函数,直到获得成功返回代码。 不同的Windows Sockets API函数,在调用失败时返回的WSAEWOULDBLOCK错误代码具有不同的含义
需要说明的是并非所有的 Windows Sockets API 在非阻塞模式下调用,都会返回 WSAEWOULDBLOCK 错误。例如,以非阻塞模式的套接字为参数调用 bind() 函数时,就不会返回该错误代码。当然,在调用 WSAStartup() 函数时更不会返回该错误代码,因为该函数是应用程序第一调用的函数,当然不会返回这样的错误代码。
要将套接字设置为非阻塞模式,除了使用 ioctlsocket() 函数之外,还可以使用 WSAAsyncselect() 和 WSAEventselect() 函数。当调用该函数时,套接字会自动地设置为非阻塞方式:
The WSAAsyncSelect function automatically sets socket s to nonblocking mode, regardless of the value of lEvent .
The WSAEventSelect function automatically sets socket s to nonblocking mode, regardless of the value of lNetworkEvents .
如果是阻塞模式下:
send先比较待发送数据的长度len和套接字s的发送缓冲的长度,如果len大于s的发送缓冲区的长度,该函数返回SOCKET_ERROR;如果len小于或者等于s的发送缓冲区的长度,那么send先检查协议是否正在发送s的发送缓冲中的数据,如果是就等待协议把数据发送完,如果协议还没有开始发送s的发送缓冲中的数据或者s的发送缓冲中没有数据,那么 send就比较s的发送缓冲区的剩余空间和len,如果len大于剩余空间大小,send就一直等待协议把s的发送缓冲中的数据发送完,如果len小于剩余空间大小send就仅仅把buf中的数据copy到剩余空间里
如果是非阻塞模式下:
在调用socket send函数时,如果能写到socket缓冲区时,就写数据并返回实际写的字节数目,当然这个返回的实际值可能比你所要写的数据长度要小些(On nonblocking stream oriented sockets, the number of bytes written can be between 1 and the requested length, depending on buffer availability on both the client and server computers),如果不可写的话,就直接返回SOCKET_ERROR了,所以没有等待的过程。。
经过上面的介绍后,下面介绍如何设置socket的非阻塞模式:
当使用socket()函数和WSASocket()函数创建套接字时,默认都是阻塞的。在创建套接字之后,通过调用ioctlsocket()函数,将该套接字设置为非阻塞模式。
//-------------------------
// Set the socket I/O mode: In this case FIONBIO
// enables or disables the blocking mode for the
// socket based on the numerical value of iMode.
// If iMode = 0, blocking is enabled;
// If iMode != 0, non-blocking mode is enabled.
u_long iMode = 1; //non-blocking mode is enabled.
ioctlsocket(m_socket, FIONBIO, &iMode); //设置为非阻塞模式
套接字设置为非阻塞模式后,在调用Windows Sockets API函数时,调用函数会立即返回。大多数情况下,这些函数调用都会调用“失败”,并返回WSAEWOULDBLOCK错误代码。说明请求的操作在调用期间内没有时间完成。通常,应用程序需要重复调用该函数,直到获得成功返回代码。 不同的Windows Sockets API函数,在调用失败时返回的WSAEWOULDBLOCK错误代码具有不同的含义
需要说明的是并非所有的 Windows Sockets API 在非阻塞模式下调用,都会返回 WSAEWOULDBLOCK 错误。例如,以非阻塞模式的套接字为参数调用 bind() 函数时,就不会返回该错误代码。当然,在调用 WSAStartup() 函数时更不会返回该错误代码,因为该函数是应用程序第一调用的函数,当然不会返回这样的错误代码。
要将套接字设置为非阻塞模式,除了使用 ioctlsocket() 函数之外,还可以使用 WSAAsyncselect() 和 WSAEventselect() 函数。当调用该函数时,套接字会自动地设置为非阻塞方式:
The WSAAsyncSelect function automatically sets socket s to nonblocking mode, regardless of the value of lEvent .
The WSAEventSelect function automatically sets socket s to nonblocking mode, regardless of the value of lNetworkEvents .
相关文章推荐
- 看到关于socket非阻塞模式设置方式记录一下。
- 关于手机的CPU和GPU,看到了,纪念一下!并且记录一下手机、平板电脑、MP5的学习。
- 记录一下socket中常见的TCP设置
- Linux下socket设置为非阻塞方式和fcntl系统调用
- 关于C# socket多线程的7个问题.希望大家发表一下意见.
- 从国外某著名DNN 知情人士 Nina's Blog上看到一些有用的文章,在此记录一下,也为国内DNN,问题搜索,出一点力
- 从国外某著名DNN 知情人士 Nina's Blog上看到一些有用的文章,在此记录一下,也为国内DNN,问题搜索,出一点力
- 前段时间看到的一个处理GIF图像的方法,记录一下
- 最近被一个socket占用搞的头疼,记录一下netstat用法
- 关于软件防止破解的思考,如何避免简单的跳转指令型的验证方法,如何设置更复杂的验证方式。
- 关于软件防止破解的思考,如何避免简单的跳转指令型的验证方法,如何设置更复杂的验证方式。
- 关于母版页的问题做一下小记录!
- 关于InstallShield Express-快捷方式的工作目录的设置
- SOCKET学习第二阶段(关于学习阻塞模式和非阻塞模式)
- iphone设置非阻塞模式socket两种方法
- 基于applet与ServerSocket的网络聊天室(记得是上学的时候写的,现在都忘了,记录一下)
- 整理了一下网上关于选购笔记本的小窍门,自己做个记录,备用
- 记录一下,关于错误提示:could not find a part of path “X:\”的解决办法
- 非阻塞模式的设置、设置socket为非阻塞模式 解决connect阻塞问题
- 在论坛里看到别人推荐的书,记录一下