WSAEventSelect是提供以网络事件的异步方式通知模型,为套接字注册网络事件后等待通知,故是被动发生的。具体流程可以参照如下图
MSDN的网络事件
Network event |
Re-enabling function |
FD_READ |
The recv, recvfrom, WSARecv, WSARecvEx, or WSARecvFrom function. |
FD_WRITE |
The send, sendto, WSASend, or WSASendTo function. |
FD_OOB |
The recv, recvfrom, WSARecv, WSARecvEx, or WSARecvFrom function. |
FD_ACCEPT |
The accept, AcceptEx, or WSAAccept function unless the error code returned is WSATRY_AGAIN indicating that the condition function returned CF_DEFER. |
FD_CONNECT |
None. |
FD_CLOSE |
None. |
FD_QOS |
The WSAIoctl function with command SIO_GET_QOS. |
FD_GROUP_QOS |
Reserved. |
FD_ROUTING_ INTERFACE_CHANGE |
The WSAIoctl function with command SIO_ROUTING_INTERFACE_CHANGE. |
FD_ADDRESS_ LIST_CHANGE |
The WSAIoctl function with command SIO_ADDRESS_LIST_CHANGE |
能够熟练运用WSAEventSelect必须注意以下5点
1、 必须创建事件表和套接字表,并把监听套接字放到表的首位。
① 、对于TCP而言:关联监听套接字必须处理 (FD_ACCEPT或者FD_CONNECT) 和FD_CLOSE事件。监听套接字不参与通信 ,故FD_WRITE 不需要关联。而由通信套接字创建的网络事件则按连接顺序放到事件表和套接字表。这时需要处理的事件有FD_READ 和FD_CLOSE 和FD_WRITE。
② 对于UDP不存在连接,故只需要处理FD_WRITE 或者FD_READ 就可以、
2、 什么是“WSAEnumNetworkEvents函数会自动重置受信事件”!
大家知道WSAEnumNetworkEvents是查询套接字上的发生的网络事件和出错代码。然而对于第二个参数,hEventObject。其实重置受信事件则是清除系统内部的网络事件记录。当调用一次WSAEnumNetworkEvents 返回event(WSAEVENT)事件 ,接下来就应该是处理该事件的代码。如果没有清除该事件对象的网络事件,那么有可能出现不断处理的该事件的结果。
3、 一个连接关闭时应该在事件表和套接字表中删除该套接字和事件。并在事件表和套接字表上把其他的前移。以便省留更多的位置给新的连接,要知道在不创建线程池的情况下,WSAEventSelect模型最多也就是能支持64 -1个连接、
4、 如果同时有几个事件对象受信WSAWaitForMultipleEvents函数只返回,最前面的一个,因此要从最前面受信事件开始逐个检查后面的受信事件,此时使用WSAWaitForMultipleEvents就要设置超时返回了,也就是dwTimeout参数、
5、 IP地址与套接字的关联问题,在接受众多连接后想要向某一连接发送数据,则需要找到该IP地址(或者主机名也行)与服务器建立的通信套接字。那么套接字表就不能是简单的套接字集合了,或许可以这样
struct SOCKET_ADDR //用来记录客户区信息的对象
{
SOCKET s;
sockaddr_in in_addr;
};
而套接字表为
SOCKET_ADDR sockArray[64];
::更加受欢迎的做法就是符合面向对象套接字链表了。
typedef struct _SOCKET_OBJ
{
SOCKET s; // 套节字句柄
HANDLE event; // 与此套节字相关联的事件对象句柄
sockaddr_in addrRemote; // 客户端地址信息
_SOCKET_OBJ *pNext;// 指向下一个SOCKET_OBJ对象,为的是连成一个表
} SOCKET_OBJ, *PSOCKET_OBJ;
posted on 2011-08-24 21:25
Yu_ 阅读(1096)
评论(0) 编辑 收藏 引用 所属分类:
网络编程