当前位置: 首页 > >

学*笔记(05):C++网络编程进阶-IO模型之WSAAsyncSelect

发布时间:

立即学*:https://edu.csdn.net/course/play/6082/113756?utm_source=blogtoedu


WsaAsyncSelect模型


异步选择模型是一个有用的异步IO模型,利用这个模型,应用程序可在一个套接字上,接收以windows消息为基础的网络事件通知。


WSAAsyncSelect函数:int WSAAsyncSelect(SOCKET s , HWND hwnd,unsigned int wMsg , long IEvent);


参数:


第一个参数:套接字


第二个参数:收到通知消息的那个窗口


第三个参数:指定在发生网络事件时接收的消息


第四个参数:指定位掩码,网络事件的组合FD_READ , FD_WRITE , FD_ACCEPT , FD_CONNECT , FD_CLOSE


返回值:


‘成功返回0 , 否则返回SOCKET_ERROR错误,通过WSAGetLastError()获取错误代码


消息处理:


网络事件消息抵达一个窗口例程后,IParam的高字位,以判断是否在网络错误,WSAGETLASTERROR宏:可以用它返回高字位包含的错误信息


若应用程序发现套接字上没有产生任何错误,接着读取IParam低字位的内容是哪个网络事件类型。


WSAGETLASTERROR宏,用它返回IParam的低字位


消息处理格式


SOCKET socket = (SOCKET) wParam;//发生网络事件的套接字


int error = WSAGESELECTERROR(IParam)//错误码


switch(WSAGETSELECTEVENT(IParam))


{


case FD_READ:


break ;


case FD_WRITE:


break ;


}


多个事件务必在套接字上一次注册。一旦在某个套接字上允许了事件通知,那么以后除非明确调用closesocket命令,或者由应用程序针对那个套接字调用了WSAAsyncSelect,从而更改了注册的网络事件类型,否则的话,事件通知会永远有效,若将IEvent参数设置为0 ,效果相当于停止在套接字上进行所有网络事件通知。


若应用程序针对一个套接字调用WSAAsyncSelect,本函数自动将套接口设置为非阻塞模式,如果调用了向WSARecv这样的Winsock函数,但当时却没有数据可用,必然会造成调用的失败,返回WSAEWOULDBLOCK错误。


所以应用程序应依赖于WSAAsyncSelect的uMsg参数指定的用户自定义窗口消息,来判断网络事件类型何时在套接字上发生。


FD_READ 应用程序想要接受有关是否可读的通知,以便读入数据


FD_WRITE 应用程序想要接受有关和可写的通知,以便写入数据


FD_ACCEPT 应用程序下想要接受与进入链接有关的通知


FD_CONNECT 应用程序想要接受与一次连接完成的通知


FD_CLOSE 应用程序想要接受与套接字关闭的通知。


只有在三种条件下才会发出FD_WRITE通知:


使用connect或WSAConnect,一个套接字首次建立了连接


使用accept或WSAAccept,套接字被接受以后


若send,SWASend,sendto,或WSASendTo操作失败,返回WSAECOULDBLOCK错误,而缓冲区的空间变得可用。


FD_WRITE事件说明socket已经准备好了,你可以调用send了,如果未收到消息,调用send会失败。


WSAAsyncSelect模型与select模型的区别


相同点


都可以对多个套接字管理


不同点


1、首先WSAAsyncSelect模型是异步的,且通知方式基于Windows环境消息,使用该模型时必须创建窗口,select模型不需要创建窗口。


2、应用程序在调用WSAAsyncSelect函数后,套接字就被设置为非阻塞状态,而使用select函数不改变套接字的工作方式。




友情链接: