网络编程笔记WSAAsyncSelect模型herocao的博客.docx
- 文档编号:23805093
- 上传时间:2023-05-20
- 格式:DOCX
- 页数:7
- 大小:16.94KB
网络编程笔记WSAAsyncSelect模型herocao的博客.docx
《网络编程笔记WSAAsyncSelect模型herocao的博客.docx》由会员分享,可在线阅读,更多相关《网络编程笔记WSAAsyncSelect模型herocao的博客.docx(7页珍藏版)》请在冰豆网上搜索。
网络编程笔记WSAAsyncSelect模型herocao的博客
网络编程笔记----WSAAsyncSelect模型--herocao的博客
Winsock提供了一个有用的异步I/O模型。
利用这个模型,应用程序可在一个套接字上,
接收以Windows消息为基础的网络事件通知。
具体的做法是在建好一个套接字后,调用
WSAAsyncSelect函数。
此模型提供了读写数据能力的异步通知,但不提供异步数据传送。
异步数据传送有“重叠及完成端口模型提供”。
消息通知
要想使用WSAAsyncSelect模型,在应用程序中,首先必须用CreateWindow函数创建一个窗口,再为该窗口提供一个窗口例程支持函数(Winproc)。
亦可使用一个对话框,为其提供一个对话例程,而非窗口例程,因为对话框本质也是“窗口”。
intWSAAsyncSelect(
SOCKETs,//要进行操作的SOCKET
HWNDhWnd,//要绑写的窗口句柄(当事件发生后要接收消息的窗口)
unsignedintwMsg,//网络事件发生时的的消息响应
longlEvent//感兴趣的网络事件,请查阅MSDN
);
使用方法可分为:
(1)初始化套接字相关信息:
(2)开始启动一个事件通知。
WSAAsyncSelect(Sock,hWnd,自定义消息,网络事件)
(3)响应窗口的自定义消息处理函数, 其中lparam的高位字包含了可能出现的错误
代码,低字节表示发生的网络事件。
wParam表示发生网络事件的套接字。
WSAGETSELECTERROR(lParam);//查看是否出现错误,获取低字节位
WSAGETSELECTEVENT(lParam);//查看发生了什么事件,获取高字节位
事件种类请查看MSDN,可用WSAGetLastError()来获取错误息。
注意:
多个事件必须一次注册完成,一旦在某个套接字上启用了事件通知,注册过的事件将一直有效,除非明确调用closesocket命令,或针对这个套接字再调用WSAAsyncSelect更改注册过的网络事件。
优点:
可在系统开销不大的情况下同时处理许多连接。
缺点:
即使用不需要窗口(如服务器,控制台)它也不得不额外使用一个窗口。
同时如果处理成千上万套接字的所有事件,性能可想而知。
MFC的CSocket所使用的正是这种事件通知模型
今天看了一下,消息通知的几个类型。
用的比较多的可能就是FD_SEND,FD_WRITE,在网上查了一下资料,总结如下:
【FD_WRITE事件】
(1)呼叫WSAAsyncSelect()来设定FD_WRITE事件时,Socket已经可以传送资料(TCPscoket已经和对方连接成功了,或UDPsocket已建立完成),且目前outputbuffer仍有空间可写入资料。
(2)呼叫WSAAsyncSelect()来设定FD_WRITE事件时,Socket尚不能传送资料,不过一旦Socket与对方连接成功,马上就会收到FD_WRITE的通知。
(3)呼叫send()或sendto()传送资料时,系统告知错误,且错误码为10035WSAEWOULDBLOCK(呼叫WSAGetLastError()得知这项错误),这时表示outputbuffer已经满了,无法再写入任何资料(此时即令呼叫再多次的send()也都一定失败);一旦系统将部份资料成功送抵对方,空出outputbuffer后,便会送一个FD_WRITE给使用者,告知可继续传送资料了。
换句话说,读者在呼叫send()传送资料时,只要不是返回错误10035的话,便可一直继续呼叫send()来传送资料;一旦send()回返错误10035,那麽便不要再呼叫send()传送资料,而须等收到FD_WRITE后,再继续传送资料。
如果只是发送很少的数据,可能只出现第二种情况,所以在发送少量数据的时候,不要使用FD_WRITE机制。
【FD_READ事件】
(1)呼叫WSAAsyncSelect函式来对此Socket设定FD_READ事件时,inputbuffer中已有资料。
(2)原先系统的inputbuffer是空的,当系统再收到资料时,会通知我们。
(3)使用者呼叫recv或recvfrom函式,从inputbuffer读取资料,但是并没有一次将资料读光,此时会再驱动一个FD_READ事件,表示仍有资料在inputbuffer中。
读者必须注意:
如果我们收到FD_READ事件通知的讯息,但是我们故意不呼叫recv或recvfrom来读取资料的话,尔後系统又收到资料时,并不会再次通知我们,一定要等我们呼叫了recv或recvfrom後,才有可能再收到FD_READ的事件通知。
下面是一个利用WSAAsyncSelect的小程序:
WORDwVersionRequested;
WSADATAwsaData;
interr;
wVersionRequested=MAKEWORD(2,2);
err=WSAStartup(wVersionRequested,&wsaData);
if(err!
=0)
{
return;
}
if(LOBYTE(wsaData.wVersion)!
=2||
HIBYTE(wsaData.wVersion)!
=2)
{
WSACleanup();
return;
spanlang="EN-US"style="LINE-HEIGHT:
150%;FONT-FAMILY:
宋体;mso-bidi-font-size:
10.5pt;mso-font-kerning:
0pt;mso-bidi-font-family:
AdobeSongStd-Light-Acro">}
charhostname[256];
gethostname(hostname,sizeof(hostname));//这一代码是为
HOSTENT*hos=gethostbyname(hostname);//了实现自动获取安
CStringCS=inet_ntoa(*(structin_addr*)hos->h_addr_list[0]);//装程序的主机代码
SOCKETserverSocket;
serverSocket=socket(AF_INET,SOCK_STREAM,0);
SOCKADDR_INaddr;
addr.sin_family=AF_INET;
addr.sin_port=htons(6000);
addr.sin_addr.S_un.S_addr=inet_addr(CS);
bind(serverSocket,(SOCKADDR*)&addr,sizeof(SOCKADDR));
//注册网络事件
if(SOCKET_ERROR==WSAAsyncSelect(serverSocket,m_hWnd,WM_NETMESSAGE,FD_ACCEPT|FD_CLOSE))
{
MessageBox("注册事件出错!
");
closesocket(serverSocket);
WSACleanup();
return;
}
listen(serverSocket,5);
}
voidCAsyselectsrvDlg:
:
Onrecvmessage(WPARAMwParam,LPARAMlParam)
{
if(WSAGETSELECTERROR(lParam))
{
AfxMessageBox("接受消息错误");
closesocket(wParam);
return;
}
switch(WSAGETSELECTEVENT(lParam))
{
caseFD_ACCEPT:
acceptclient(wParam,m_hWnd);
break;
caseFD_WRITE:
MessageBox("write");
break;
caseFD_READ:
MessageBox("read");
break;
caseFD_CLOSE:
closesocket(wParam);
break;
default:
break;
}
return;
}
voidacceptclient(SOCKETsock,HWNDhwnd)
{
SOCKETacceptclient;
SOCKADDR_INclientaddr;
intlen=sizeof(SOCKADDR_IN);
acceptclient=accept(sock,(structsockaddr*)&clientaddr,&len);
if(SOCKET_ERROR==WSAAsyncSelect(acceptclient,hwnd,WM_NETMESSAGE,FD_READ|FD_WRITE|FD_CLOSE))
{
AfxMessageBox("注册消息出错!
");
closesocket(sock);
closesocket(acceptclient);
WSACleanup();
return;
}
}
这段程序可以正常运行,前面定义全局函数:
voidacceptclient(SOCKETsock,HWNDhwnd);
今晚就写到这里了。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 网络 编程 笔记 WSAAsyncSelect 模型 herocao 博客