套接字的属性

来源:互联网 发布:淘宝联盟软件推广赚钱 编辑:程序博客网 时间:2024/04/28 21:47

    以前我总是将是否处于阻塞模式和是否可以进行异步IO操作混淆起来。以前,我认为可以进行异步IO操作的套接字必然不是处于阻塞模式;处于阻塞模式的套接字无法进行异步IO操作。最新比较正规地学习win socket开发,终于分清这两个概念。

    其实,是否处于阻塞模式、是否可以进行异步IO操作是一个套接字上两个不相关的属性。

    首先,所有的winsock函数可以分成阻塞函数和非阻塞函数。

    套接字是否处于阻塞模式,只会影响阻塞函数的行为。阻塞函数是指,在套接字上调用该函数后,在某些条件下函数可能会阻塞住不会返回。例如,recv就是一个阻塞函数,如果当前套接字上没有数据,那么调用recv之后线程可能被阻塞住。如果一个套接字处于阻塞模式,在没有数据的情况下调用recv就会阻塞当前线程;如果一个套接字处于非阻塞模式,在没有数据的情况下调用recv后会立即返回,返回值为-1,错误码为WSAEWOULDBLOCK。

    对于非阻塞函数,比如bind, socket。无论套接字处于阻塞模式,还是处于非阻塞模式。非阻塞函数都不会阻塞当前线程。

    其次,是否指定WSA_FLAG_OVERLAPPED标识只影响异步IO操作函数的行为。

   一个套接字创建时是否指定WSA_FLAG_OVERLAPPED标识,不会影响bind, accept等阻塞函数的行为。异步IO函数,指的是那些具有LPOVERLAPPED参数的API,比如WSARecv, WSASend等。如果一个套接字不支持异步IO操作,在该套接字上调用WSARecv等异步IO函数,IO操作将以同步的方式执行。在同步执行的情况下,异步IO函数是否会阻塞调用线程与套接字是否处于阻塞模式有关。

    最后,所有的套接字默认处于阻塞模式。

    通过调用WSAAsyncSelect, WSAEventSelect, WSAIoctl可以改变套接字的模式。


原创粉丝点击