0);if(flag==0){MessageBox(_T("连接已经断开"));return 0;}ShowMsg(bu

时间:2022-02-08 05:25:49

异步选择(WSAAsyncSelect)模型是一个有用的异步I/O 模型。其核心函数是WSAAsyncSelect,

(关于异步io的理解详情可以看:)

它可以用来在一个socket上接收以windows动静为根本的网络事件。它供给了读写数据的异步通知成果,但不供给异步数据传送。WSAAsyncSelect模型的优势在于只需要一个主线程即可。错误谬误是必需要绑定窗口句柄。即要先挪用createwindow创建一个窗口。这也就是为什么这个模型只适用于windows操纵系统而不能跨平台的原因。

WSAAsyncSelect 的函数原型如下:

int WSAAsyncSelect( 

__in         SOCKET s,

  __in         HWND hWnd,

  __in         unsigned int wMsg,

  __in         long lEvent

);

 s 参数指定的是我们感兴趣的阿谁套接字。

● hWnd 参数指定一个窗口句柄,它对应于网络事件产生之后,想要收到通知动静的阿谁窗口。

● wMsg 参数指定在产生网络事件时,筹算接收的动静。该动静会投递到由hWnd窗口句柄指定的阿谁窗口。

(凡是,应用措施需要将这个动静设为比Windows的WM_USER大的一个值,制止网络窗口动静与系统预界说的标准窗口动静产生混淆与斗嘴)

(即自界说动静)

● lEvent 参数指定一个位掩码,对应于一系列网络事件的组合,大大都应用措施凡是感兴趣的网络事件类型包孕:

FD_READ、FD_WRITE、FD_ACCEPT、FD_CONNECT、FD_CLOSE。固然,到底使用FD_ACCEPT,还是使用FD_CONNECT类型,

要取决于应用措施的身份是客户端,还是处事器。如应用措施同时对多个网络事件有兴趣,只需对各类类型执行一次简单的按位OR(或)运算,

然后将它们分配给lEvent就可以了,例如:

WSAAsyncSeltct(s, hwnd,WM_SOCKET, FD_CONNECT | FD_READ | FD_WRITE | FD_CLOSE);

解释说明:我们的应用措施以后便可在套接字s上,接收到有干系接、发送、接收以及套接字*这一系列网络事件的通知。

FD_READ       应用措施想要接收有关是否可读的通知,以便读入数据

FD_WRITE   应用措施想要接收有关是否可写的通知,以便写入数据

FD_ACCEPT     应用措施想接收与进入连接有关的通知

FD_CONNECT 应用措施想接收与一次连接完成的通知

FD_CLOSE   应用措施想接收与套接字*的通知

注意 ①

多个事件务必在套接字上一次注册!

此外还要注意的是,一旦在某个套接字上允许了事件通知,那么以后除非明确挪用closesocket命令,

或者由应用措施针对阿谁套接字挪用了WSAAsyncSelect,,从而变动了注册的网络事件类型,否则的话,

事件通知会永远有效!若将lEvent参数设为0,效果相当于遏制在套接字长进行的所有网络事件通知。

注意 ②:

若应用措施针对一个套接字挪用了WSAAsyncSelect,那么套接字的模式会自动从“梗阻”酿成“非梗阻”。

这样一来,如果挪用了像WSARecv这样的Winsock函数,但其时却并没有数据可用,那么一定会造成挪用的掉败,并返回WSAEWOULDBLOCK错误。

为防备这一点,应用措施应依赖于由WSAAsyncSelect的uMsg参数指定的用户自界说窗口动静,来判断网络事件类型何时在套接字上产生;而不应盲目地进行挪用。

 

应用措施在一个套接字上告成挪用了WSAAsyncSelect之后,会在与hWnd窗口句柄对应的窗口类中,以Windows动静的形式,接收网络事件通知

窗口例程凡是界说如下:

LRESULT CALLBACK WindowProc(

    HWND hwnd,

    UINT uMsg,

    WPARAM wParam,

    LPARAM lParam

);

● hWnd 参数指定一个窗口的句柄,对窗口例程的挪用正是由阿谁窗口发出的。

● uMsg 参数指定需要对哪些动静进行措置惩罚惩罚。这里我们感兴趣的是WSAAsyncSelect挪用中界说的动静。

● wParam 参数指定产生网络事件的socket。假若同时为这个窗口例程分配了多个套接字,这个参数的重要性便显示出来了。