您的位置:首页 > 其它

WinSock IO模型二: WSAAsyncSelect 消息机制

2013-03-19 22:45 507 查看
WSAAsyncSelect基于Windows消息机制异步I/O模型,为特定网络事件指定系统通知信息.

函数定义: int WSAAsyncSelect(SOCKET s, HWND hWnd, unsigned int wMsg, long lEvent);

(1)参数4-1Event:设定用户关心得套接口上的网络事件.形式如:1Event=FD_READ/FD_CLOSE.

网络I/O事件 简表

事件值 含义 触发条件

FD_READ 套接口有可读消息通知 recv,recvfrom,WSARecv或WSARecvFrom

FD_WRITE 套接口有可发消息通知 send,sendto,WSASend或WSASendTo

FD_OOB 套件口有外带数据消息通知 recv,recvfrom,WSARecv或WSARecvFrom

FD_ACCEPT 套接口有链接请求消息通知 accept或WSAAccept(错误码不能WSATRY_AGAIN)

FD_CONNECT 希望得到connect或多点join操作完成信息通知 无

FD_CLOSE(面向连接) 套接口关闭消息通知 无

FD_QOS 套接口QOS状态发生变化消息通知 WSAIoctl(SIO_GET_QOS)

FD_GROUP_QOS 保留 Reserved

FD_ROUTING_INTERFACE_CHANGE

特定方向的路由接口发生改变消息通知。 WSAIoctl(SIO_ROUTING_INTERFACE_CHANGE)

FD_ADDRESS_LIST_CHANGE

得到本地地址列表上套接口协议族发生改变通知。 WSAIoctl(SIO_ADDRESS_LIST_CHANGE)

(2)参数3-wMsg:为套接口事件设定1Event通知消息通常形式(WM_USER + n)

如 #define WM_USER_SERVER WM_USER+1

(3)参数2-bWnd指定系统通知消息wMsg的窗口句柄.

函数若调用成功, WSAAsyncSelect返回0; 否则返回SOCKET_ERROR, 这时可用WSAGetLastError来获取错误码.

事实上,成功发送一次消息,通知机制会暂停工作直到有重新激活消息通知机制到来.才可重新激活事件.

水平触发:FD_READ,FD_OOB和FD_ACCEPT 即重新激活,需要引发消息发送的条件.

边缘触发:FD_QOS,FD_GROUP_QOS等.

同一接口多次调用WSAAsyncSelect函数,只有最后一次生效.

因此:

WSAAsyncSelect(s, m_hWnd, WM_USER_SERVER, FD_READ),加上

WSAAsyncSelect(s, m_hWnd, WM_USER_SERVER, FD_CLOSE) 并不等于

WSAAsyncSelect(s, m_hWnd, WM_USER_SERVER, FD_READ | FD_CLOSE)

取消套接口上的I/O事件消息通知:、

WSAAsyncSelect(s, hWnd, 0, 0)

在MFC编程环境中,使用该消息处理函数

BEGIN_MESSAGE_MAP(CXXXDlg, CDialog)

//{{AFX_MSG_MAP(CXXXDlg)

........

//}}AFX_MSG_MAP

ON_MESSAGE(WM_USER_SERVER, OnServerMsg)

........

END_MESSAGE_MAP()

处理消息函数声明为:

afx_msg void OnSERVERMsg(WPARAM wparam,LPARAM lParam);

它定义为:

void CXXXDlg::OnServerMsg(WPARAM wParam,LPARAM lParam)

{

SOCKET sock = (SOCKET) wParam;

if(WSAGETSELECTERROR(lParam)){

ErrorProcess();

return;

}

switch(WSAGETSELECTEVENT(lParam)){

case FD_READ:

ReadDate(sock); // 读数据并进行相应处理

break;

case FD_CLOSE:

Finsish(sock); //套接口关闭工作

break;

default;

break;

}

}

其中函数会接受到两个参数wParam 和 lParam。

其中 wParam参数 指明网络事件套接口,多个套接口指定同一个用户消息,那么就需要根据wParam判断到底是哪个套接口待处理。

lParam参数包含两信息:底字指定发生网络事件,高字包含可能出现错误带代码。

另外 OnServerMsg函数中出现两个宏定义

#define WSAGETSELECTERROR(lParam) HIWORD(lParam)

#define WSAGETSELECTEVENT(lparam) LOWORD(lParam)

一般来讲,当用户 收到第一个FD_WRITE用户消息时就可以向套接口写数据,直到碰到WSAEWOULBALOCK错误时才

等待下一次FD_WRITE通知消息。

总结:WSAAsynSelect在MFC中使用流程

(1)、使用#define语句定义套接口网络事件设置用户消息值,一般为WM_USER+N形式。

(2)、调用WSAAsynsSelect函数,为套接口设定"网络事件-用户消息-消息接收窗体"的对应关系。

(3)、在消息接收窗体的代码的消息映射模块中,加入ON_MESSAGE宏,设定用户消息的处理函数。

(4)、编写用户处理函数,该函数应该首先使用WSAGETSELECTERROR宏判断是否有错误发生:

然后根据wParam值了解是哪一个套接口上发生了网络事件从而引起用户消息被发送:最后使用

WSAGETSELECTEVENT宏来了解所发生的网络事件,从而进行相应处理。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: