网络软件设计8——异步响应

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

网络软件设计Win32Socket异步消息机制WSAAsyncSelect()制作主讲段景山段景山2消息驱动与Socket服务机制的矛盾阻塞?造成主线程无法响应窗口消息非阻塞?设置套接字为非阻塞状态(见课件9)主线程忙等无法响应窗口消息select?主线程受select机制影响仍无法响应窗口消息多线程并发服务?子线程可以独立工作,不致影响主线程响应消息但主线程一旦需要循环等待接受客户连接,仍出现以上问题基于windows消息的循环基于select的循环段景山3矛盾的根源使用套接字时的循环机制循环等待客户连接循环等待客户数据在窗口程序中循环或阻塞都会影响主线程对消息的响应while(1){ns=accept(sock,…);…}while(recv0){len=recv(sock,…);…}事件段景山4解决矛盾方案一为所有需要循环等待的程序段生成线程为需要循环等待客户连接的部分生成子线程为需要循环等待数据、完成通信的部分生成子线程窗口函数clickstartwhile(1){accept();}while(1){recv();}客户connect客户connectwhile(1){recv();}段景山5解决矛盾方案二不在程序中循环等待如何促使程序不断接受客户连接,接收数据?窗口函数clickstartselect();while(1){}窗口程序是基于消息的,如果将客户连接、数据到达等也映射为消息则通信程序也可以基于消息驱动,不必自己去循环等待——异步响应WSAAsyncSelect()段景山6WSAAsyncSelect()异步选择机制使用WSAAsyncSelect()注册网络事件当套接字上出现出现相应的事件时,会用消息通知窗口函数处理接受连接接收数据连接被关闭……WSAAsyncSelect()参数设计套接字窗口句柄消息,事件段景山7WSAAsyncSelect()函数说明intWSAAsyncSelect(SOCKETs,HWNDhWnd,unsignedintwMsg,longlEvent)wMsg:套接字消息,如UM_SOCK,该消息通过以下方式定义#defineUM_SOCKWM_USER+1lEvent:套接字事件,事件类型有FD_READFD_WRITEFD_ACCEPTFD_CONNECTFD_CLOSEFD_OOB有数据接收可以发送有客户建立连接与服务器建立连接,或连接失败connet的结果连接被关闭带外(紧急)数据到达段景山8WSAAsyncSelect()函数功能及使用方法说明该函数用于将指定的套接字上发生的指定消息及事件向指定窗口注册当套接字上发生指定事件时,系统会通过消息机制通知指定的窗口函数处理intWSAAsyncSelect(SOCKETs,HWNDhWnd,unsignedintwMsg,longlEvent)指定套接字指定消息指定事件指定窗口WinMainWndProcWndProcWndProcDispatchMessage()段景山9WSAAsyncSelect()函数功能及使用方法说明该函数用于将指定的套接字上的指定消息及事件向指定窗口注册当套接字上发生指定事件时,系统会通过消息机制通知指定的窗口函数处理换言之,如果不事先注册,套接字上的事件不会通知窗口函数注册多个事件时,使用以下方式WSAASyncSelect(s,hWnd,UM_SOCK,FD_READ|FD_ACCEPT|FD_CLOSE);当窗口收到套接字消息后,message为UM_SOCK,事件用lParam通知,发生事件的套接字标识符由wParam通知使用了WSAAsyncSelect的套接字自动变成非阻塞状态select不具有这个功能可以自己定义系统定义段景山10WSAAsyncSelect()函数功能及使用方法说明与select不同的是,注册只需进行一次,系统会一直保持对事件的敏感,直到重新注册第二次注册时,会取消上次注册的消息例:下面两段程序并不等价WSAAsyncSelect(s,hWnd,UM_SOCK,FD_READ|FD_WRITE);希望系统对s上的FD_READ和FD_WRITE事件进行通知WSAAsyncSelect(s,hWnd,UM_SOCK,FD_READ);WSAAsyncSelect(s,hWnd,UM_SOCK,FD_WRITE);系统仅对s上的FD_WRITE事件进行通知段景山11异步选择机制对消息/事件的注册用于实现不同功能的套接字,可能注册不同的事件对事件的响应事件使能(重新允许)更多的错误处理段景山12异步选择机制对消息/事件的注册服务器主套接字上注册FD_ACCEPT事件从套接字上注册FD_READ|FD_CLOSE等事件客户机套接字注册FD_CONNECT事件对事件的响应判断为UM_SOCK消息后,进一步获得套接字标识符和事件根据事件,在套接字上调用相应函数FD_ACCEPT----accept(s)FD_READ----recv(s),read(s)FD_CONNECT---连接已建立,客户可以发出数据了FD_CLOSE-----closesocket(s)FD_WRITE-----send(s),write(s)事件使能(重新允许)Windows对用户产生事件后,如果用户没有对事件处理,Windows将不对用户继续产生事件。必须针对每个事件进行处理,以使系统继续产生新的事件段景山13例服务器程序(与前一部分的程序相比)在StartServer()中使用WSAAsyncSelect而不是用循环的方式等待accept在窗口函数中添加UM_SOCK类消息,并进一步添加对各事件的处理bind(mainsock,…);listen(mainsock,…);WSAAsyncSelect(mainsock,hWnd,UMSOCK,FD_ACCEPT)段景山14例套接字消息处理WndProc(…){switch(message){caseUM_SOCK:id=LOWORD(lParam);sock=wParam;switch(id){caseFD_ACCEPT:ns=accept(sock,…);WSAAsyncSelect(ns,…,FD_READ|FD_CLOSE);caseFD_READ:recv(sock,buf…);……段景山15例客户机程序在start中,调用connect,但要注意,connect返回时,并不意味着连接已建立,需要等待FD_CONNECT事件在窗口函数中增加套接字事件处理sock=socket(……);WSAAsyncSelect(sock,……,FD_CONNECT);填写server的IP地址和端口号;connect(sock,server,…);段景山16例套接字消息处理WndProc(…){switch(message){caseUM_SOCK:event=LOWORD(lParam);sock=wParam;switch(event){caseFD_CONNECT:if(HIWORD(lParam)==0){WSAAsyncSelect(sock,,UM_SOCK,FD_READ|FD_CLOSE);}else{closesocket(sock);}break;caseFD_READ:recv(sock,buf…);……段景山17异步选择机制事件使能(重新允许)实验:在出现FD_READ事件后,没有调用recv(),观察系统是否再次产生FD_READ事件。对比实验:出现FD_READ事件后,调用recv()接收,不管是否接收完,系统都会根据需要继续产生FD_READ事件段景山18异步选择机制WinSock下具有重新允许功能的函数,及与相应事件的对应关系FD_READrecv()或recvfrom()FD_WRITEsend()sendto()FD_ACCEPTaccept()FD_CONNECTNONEFD_CLOSENONEFD_OOBrecv()段景山19异步选择机制更多的错误处理原因基于消息的程序机制,具有多个入口(菜单、按钮、选项…)使用者可能任意选择入口,对程序流程造成意想不到的破坏,如还未建立连接,就点击发送键方法一迫使用户按照程序设计者规定的流程。在每个阶段,将不应该进入的菜单、按钮、选项失效(变灰)方法二进行更多的错误状态判断,使每个入口的执行条件更为严格。段景山20异步选择与多路复用Windows异步选择机制中,在通知用户的消息中,也同时通知了产生事件的套接字描述符,所以有以下结论:异步选择机制支持多路服用。即可以对多个套接字同时进行事件注册,并同时处理与select相比,程序员自行管理套接字队列的功能不是必需的。winsock下的多路复用由系统支持--同时也受到系统的限制对于大型、复杂的服务器程序,程序员仍应根据需要考虑对套接字队列的管理。甚至,慎重考虑是否需要建立在windows的窗口机制下。段景山21同步选择与异步选择的比较基于select的同步选择不断查询程序框架是不断循环同步性:查询结果是套接字当时状态需要用户自行管理多个套接字以备查询不存在事件使能,即如果不处理查询得到的事件,下次查询,该事件仍然存在WSAAsyncSelect异步选择一次注册程序尽量不出现循环异步性:不保证通知用户后,用户能及时了解和处理用户不必管理套接字,事件通知中包含套接字标识符存在事件使能,如果不处理通知的事件,后续事件将不再通知,直到完成相应处理,即事件使能都支持多路服用都可以看作是事件驱动,只不过一个是查询事件,一个是等待“事件通知”

1 / 21
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功