您好,欢迎访问三七文档
当前位置:首页 > IT计算机/网络 > 数据库 > 完成端口模型程序设计
完成端口模型程序设计一.实验目的通过本次实验,掌握Windowssocket的IO完成端口(IOCP)模型开发,利用编程能力,编写程序,利用服务线程,查看I/O操作的结果信息。深入了解相关知识。二.实验任务首先查阅与完成端口模型程序设计的相关资料与技术指导,粗略制定实验的流程步骤,然后绘制程序设计的流程图,按照预先设计的流程图,进行程序的编写,在与同学老师的交流合作之下,进行程序的调试与修改,最后进行总结,记录调试结果,撰写相关实验报告三.实验设计方案①查阅技术相关资料②绘制程序流程图③按照以下步骤编写程序与调试1:创建完成端口2:将套接字与完成端口关联。3:调用输入输出函数,发起重叠IO操作。4:在服务线程中,等待完成端口重叠IO操作结果。④总结体会与改进意见⑤撰写实验报告四.算法,流程图及关键代码说明1.技术说明I/O完成端口是一种内核对象。利用完成端口,套接字应用程序能够管理数百上千个套接字。应用程序创建完成端口对象后,通过指定一定数量的服务线程,为已经完成的重叠IO操作提供服务。该模型可以达到最后的系统性能。完成端口是一种真正意义上的异步模型。在重叠I/O模型中,当Windowssocket应用程序在调用WSARecv函数后立即返回,线程继续运行。另一线程在在完成端口等待操作结果,当系统接收数据完成后,会向完成端口发送通知,然后应用程序对数据进行处理。为了将Windows打造成一个出色的服务器环境,Microsoft开发出了IO完成端口。它需要与线程池配合使用。服务器有两种线程模型:串行和并发模型。串行模型:单个线程等待客户端请求。当请求到来时,该线程被唤醒来处理请求。但是当多个客户端同时向服务器发出请求时,这些请求必须依次被请求。并发模型:单个线程等待请求到来。当请求到来时,会创建新线程来处理。但是随着更多的请求到来必须创建更多的线程。这会导致系统内核进行上下文切换花费更多的时间。线程无法即时响应客户请求。伴随着不断有客户端请求、退出,系统会不断新建和销毁线程,这同样会增加系统开销。而IO完成端口却可以很好的解决以上问题。它的目标就是实现高效服务器程序。与重叠IO相比较重叠IO与IO完成端口模型都是异步模型。都可以改善程序性能。但是它们也有以下区别:1:在重叠IO使用事件通知时,WSAWaitForMultipleEvents只能等待WSA_MAXIMUM_WAIT_EVENTS(64)个事件。这限制了服务器提供服务的客户端的数量。2:事件对象、套接字和WSAOVERLAPPED结构必须一一对应关系,如果出现一点疏漏将会导致严重的后果。1:创建IO完成端口2:将套接字与IO完成端口关联CreateIoCompletionPort(sListenSocket,hIOPort,完成键,0);调用此函数即告诉系统:当IO操作完成时,想完成端口发送一个IO操作完成通知。这些通知按照FIFO方式在完成队列中等待服务线程读取。在利用IO完成端口开发套接字应用程序时,通常声明一个结构体保存与套接字相关的信息。该结构通常作为完成键传递给CreateIoCompletionPort用以区分与套接字相关的信息。我们可以给完成键传入任何对我们有用的信息,一般情况下都是传入一个结构的地址。3:发起重叠IO操作将套接字与IO完成端口关联后,应用程序可以调用以下函数,发起重叠IO操作:WSASend和WSASendTo:发送数据。WSARecv和WSARecvFrom:接收数据。在应用程序中通常声明一个和IO操作相关的结构体,它是WSAOVERLAPPED结构的扩展。用以保存每一次IO操作的相关信息。4:等待重叠IO操作结果:服务线程启动后,调用GetQueuedCompletionStatus函数等待重叠IO操作的完成结果。当重叠IO操作完成时,IO操作完成通知被发送到完成端口上,此时函数返回。综上,在使用完成端口开发Windowssocket应用程序时,一般需要定义两种数据结构:完成键和扩展的WSAOVERLAPPED结构。完成键保存与套接字有关的信息。在GetQueuedCompletionStatus返回时可以通过该参数获取套接字的相关信息。这用于区分不同设备。扩展的WSAOVERLAPPED结构,保存每次发起IO操作时IO操作相关的信息。当GetQueuedCompletionStatus返回时通过该参数获取套接字的IO操作相关信息。5:取消异步操作。当关闭套接字时,如果此时系统还有未完成的异步操作,应用程序可以调用CancelIo函数取消等待执行的异步操作。2.流程图3.关键代码及说明/////////////////////////////////////////////EventSelectServer.cpp文件#include../common/initsock.h#includestdio.h#includewindows.h#includeEventSelectServer.h//初始化Winsock库CInitSocktheSock;intmain(){USHORTnPort=4567;//此服务器监听的端口号//创建监听套节字SOCKETsListen=::socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);sockaddr_insin;sin.sin_family=AF_INET;sin.sin_port=htons(nPort);sin.sin_addr.S_un.S_addr=INADDR_ANY;if(::bind(sListen,(sockaddr*)&sin,sizeof(sin))==SOCKET_ERROR){printf(Failedbind()\n);return-1;}::listen(sListen,200);//创建事件对象,并关联到监听的套节字WSAEVENTevent=::WSACreateEvent();::WSAEventSelect(sListen,event,FD_ACCEPT|FD_CLOSE);::InitializeCriticalSection(&g_cs);//处理客户连接请求,打印状态信息while(TRUE){intnRet=::WaitForSingleObject(event,5*1000);if(nRet==WAIT_FAILED){printf(FailedWaitForSingleObject()\n);break;}elseif(nRet==WSA_WAIT_TIMEOUT)//定时显式状态信息{printf(\n);printf(TatolConnections:%d\n,g_nTatolConnections);printf(CurrentConnections:%d\n,g_nCurrentConnections);continue;}else//有新的连接未决{::ResetEvent(event);//循环处理所有未决的连接请求while(TRUE){sockaddr_insi;intnLen=sizeof(si);SOCKETsNew=::accept(sListen,(sockaddr*)&si,&nLen);if(sNew==SOCKET_ERROR)break;PSOCKET_OBJpSocket=GetSocketObj(sNew);pSocket-addrRemote=si;::WSAEventSelect(pSocket-s,pSocket-event,FD_READ|FD_CLOSE|FD_WRITE);AssignToFreeThread(pSocket);}}}::DeleteCriticalSection(&g_cs);return0;}////////////////////////////////////////////////////////////initsock.h文件#includewinsock2.h#pragmacomment(lib,WS2_32)//链接到WS2_32.libclassCInitSock{public:CInitSock(BYTEminorVer=2,BYTEmajorVer=2){//初始化WS2_32.dllWSADATAwsaData;WORDsockVersion=MAKEWORD(minorVer,majorVer);if(::WSAStartup(sockVersion,&wsaData)!=0){exit(0);}}~CInitSock(){::WSACleanup();}};五.调试结果结果一:开启EventSelectServer,会看到,当前连接,与总连接数量都为0结果二:开启一个Client(客户端)结果三:开启客户端之后,再查看服务器端,会发现,当前连接数量与总连接数量都发生了改变,此时都为1,符合实情。结果四:开启2个客户端即关闭一个客户端关闭所有客户端六.改进意见与心得体会通过此次实验,我们掌握了Windowssocket的IO完成端口(IOCP)模型开发,利用编程能力,编写程序,利用服务线程,查看I/O操作的结果信息。深入了解相关知识。重叠IO与IO完成端口模型都是异步模型。都可以改善程序性能。但是它们也有以下区别:在重叠IO使用事件通知WSAWaitForMultipleEvents只能等待WSA_MAXIMUM_WAIT_EVENTS(64)个事件。这限制了服务器提供服务的客户端的数量。事件对象、套接字和WSAOVERLAPPED结构必须一一对应关系,如果出现一点疏漏将会导致严重的后果。本次实验中,我们通过一步步的实验,调试,发现问题,查找资料,发现错误,调试改进,直到最后完成整个实验,从实验中巩固学习到的知识,并将它适当运用,达成目标。在老师的细心指导下,与同学的配合联机调试下,此次实验,圆满完成,收益良多。七.主要参考资料《网络应用与开发》
本文标题:完成端口模型程序设计
链接地址:https://www.777doc.com/doc-2497928 .html