1.在我们直接调用socket创建时,如果不进行特意声明的话,创建的socket都是阻塞的。这样当我们调用accept,recv时,将有可 能“block”,如果想设置为非阻塞,则方法有调用fcntl,select,WSAAsynSelect 来改变socket的阻塞
hsocket = socket(AF_INET, SOCK_STREAM, 0)
fcntl(hsocket, F_SETFL, 0_NONBLOCK);
注意:
其中fcntl是Unix系统环境中使用的,使用ioctl()函数和fcntl()函数实现对套接字的控制,而在Windows系统中则应使用 ioctlsocket()函数。
Ioctl和fcntl的区别是:
ioctl - control device
ioctl() performs a variety of control functions on devices
and STREAMS. For non-STREAMS files, the functions performed
by this call are device-specific control functions. request
and an optional third argument with varying type are passed
to the file designated by fildes and are interpreted by the
device driver.
The fcntl() function provides control of open file descriptors. It is similar to ioctl().
( 这些带着unix的体味的函数,看着就头大。这个我是摘自某个文档,设置超时应该采用ioctlsocket。)
1.调用MFC的CAsyncSocket和CSocket类
MFC提供了两个类CAsyncSocket和CSocket来封装WinSock API,
CAsyncSocket在较低层次上封装了WinSock API,缺省情况下,使用该类创建的socket是非阻塞的socket,所有操作都会立即返回,如果没有得到结果,返回WSAEWOULDBLOCK, 表示是一个阻塞操作。
CSocket建立在CAsyncSocket的基础上,是CAsyncSocket的派生类。也就是缺省情况下使用该类创建的socket是非阻塞的 socket,但是CSocket的网络I/O是阻塞的,它在完成任务之后才返回。CSocket的阻塞不是建立在“阻塞”socket的基础上,而是在 “非阻塞”socket上实现的阻塞操作,在阻塞期间,CSocket实现了本线程的消息循环,因此,虽然是阻塞操作,但是并不影响消息循环,即用户仍然 可以和程序交互。(即程序不会freeze)。
其中设置超时函数如下:
CAsyncSocket::SetSockOpt( int nOptionName, const void* lpOptionValue, int nOptionLen, int nLevel = SOL_SOCKET );
nOptionName用SO_SNDTIMEO or SO_RCVTIMEO。