WSAEventSelect()
简述:确定与所提供的FD_XXX网络事件集合相关的一个事件对象。
#include <winsock2.h>
int WSAAPI WSAEventSelect ( SOCKET s, WSAEVENT
hEventObject, long lNetworkEvents );
s:一个标识套接口的描述字。
hEventObject:一个句柄,用于标识与所提供的FD_XXX网络事件集合相关的一个事件对象。
lNetworkEvents:一个屏蔽位,用于指定感兴趣的FD_XXX网络事件组合。
返回值:
如果应用程序指定的网络事件及其相应的事件对象成功设置,则返回0。否则的话,将返回INVALID_SOCKET错误,应用程序可通过WSAGetLastError()来获取相应的错误代码。
在使用select()和WSAAsyncSelect()函数时,WSAEventSelect()常用来决定何时进行数据传送操作(如send()或recv()),并期望能立即成功。但是一个稳定的应用程序应该做好这样的准备,即事件对象被设置,并且一个WinSock调用以WSAEWOULDBLOCK立即返回 。举例来说,有可能发生下述操作序列:
(i) 套接口s上到达数据;WinSock设置了WSAEventSelect事件对象。
(ii) 应用程序进行其他操作。
(iii) 在进行操作时,应用程序调用了ioctlsocket(s, FIONREAD...)并发现有数据可读。
(iv) 应用程序调用一个recv(s,...)来读取数据。
(v) 最后应用程序等待WSAEventSelect()所指定的数据对象,该数据对象指出数据可读。
(vi) 应用程序调用recv(s,...),但以WSAEWOULDBLOCK错误失败。
其他的操作序列也是可能的。
成功地记录了网络事件的发生(通过设置内部网络事件记录的相应位),并且将相应的事件对象设置了信号后,不会对该网络事件作进一步的操作,直到应用程序调用了相应的函数显式地重新允许该网络事件及相应事件对象的信号。
网络事件 重新允许函数
FD_READ recv() 或 recvfrom()
FD_WRITE send() 或 sendto()
FD_OOB recv()
FD_ACCEPT accept() 或WSAAccept(),直到返回的错误代码为 WSATRY_AGAIN,指明条件函数返回CF_DEFER。
FD_CONNECT NONE
FD_CLOSE NONE
FD_QOS 用SIO_GET_QOS 命令调用WSAIoctl()。
FD_GROUP_QOS 用SIO_GET_GROUP_QOS命令调用WSAIoctl()。
错误代码:
WSANOTINITIALISED 在调用本API之前应成功调用WSAStartup()。
WSAENETDOWN 网络子系统失效。
WSAEINVAL 参数中有非法值,或者指定的套接口处于非法状态。
WSAEINPROGRESS 一个阻塞的WinSock调用正在进行中,或者服务提供者仍在处理一个回调函数
WSAENOTSOCK 描述字不是一个套接口。
另请参阅: WSACloseEvent() , WSACreateEvent(), WSAEnumNetworkEvents(),WSAGetOverlappedResult(),WSAWaitForMultipleEvents().
#include <winsock2.h>
int WSAAPI WSAEventSelect ( SOCKET s, WSAEVENT
hEventObject, long lNetworkEvents );
s:一个标识套接口的描述字。
hEventObject:一个句柄,用于标识与所提供的FD_XXX网络事件集合相关的一个事件对象。
lNetworkEvents:一个屏蔽位,用于指定感兴趣的FD_XXX网络事件组合。
返回值:
如果应用程序指定的网络事件及其相应的事件对象成功设置,则返回0。否则的话,将返回INVALID_SOCKET错误,应用程序可通过WSAGetLastError()来获取相应的错误代码。
在使用select()和WSAAsyncSelect()函数时,WSAEventSelect()常用来决定何时进行数据传送操作(如send()或recv()),并期望能立即成功。但是一个稳定的应用程序应该做好这样的准备,即事件对象被设置,并且一个WinSock调用以WSAEWOULDBLOCK立即返回 。举例来说,有可能发生下述操作序列:
(i) 套接口s上到达数据;WinSock设置了WSAEventSelect事件对象。
(ii) 应用程序进行其他操作。
(iii) 在进行操作时,应用程序调用了ioctlsocket(s, FIONREAD...)并发现有数据可读。
(iv) 应用程序调用一个recv(s,...)来读取数据。
(v) 最后应用程序等待WSAEventSelect()所指定的数据对象,该数据对象指出数据可读。
(vi) 应用程序调用recv(s,...),但以WSAEWOULDBLOCK错误失败。
其他的操作序列也是可能的。
成功地记录了网络事件的发生(通过设置内部网络事件记录的相应位),并且将相应的事件对象设置了信号后,不会对该网络事件作进一步的操作,直到应用程序调用了相应的函数显式地重新允许该网络事件及相应事件对象的信号。
网络事件 重新允许函数
FD_READ recv() 或 recvfrom()
FD_WRITE send() 或 sendto()
FD_OOB recv()
FD_ACCEPT accept() 或WSAAccept(),直到返回的错误代码为 WSATRY_AGAIN,指明条件函数返回CF_DEFER。
FD_CONNECT NONE
FD_CLOSE NONE
FD_QOS 用SIO_GET_QOS 命令调用WSAIoctl()。
FD_GROUP_QOS 用SIO_GET_GROUP_QOS命令调用WSAIoctl()。
错误代码:
WSANOTINITIALISED 在调用本API之前应成功调用WSAStartup()。
WSAENETDOWN 网络子系统失效。
WSAEINVAL 参数中有非法值,或者指定的套接口处于非法状态。
WSAEINPROGRESS 一个阻塞的WinSock调用正在进行中,或者服务提供者仍在处理一个回调函数
WSAENOTSOCK 描述字不是一个套接口。
另请参阅: WSACloseEvent() , WSACreateEvent(), WSAEnumNetworkEvents(),WSAGetOverlappedResult(),WSAWaitForMultipleEvents().