当前位置首页 > 建筑/施工 > 施工组织
搜柄,搜必应! 快速导航 | 使用教程  [会员中心]

第三章_overlappedIO

文档格式:PPT| 28 页|大小 429.50KB|积分 10|2024-02-03 发布|文档ID:239513274
第1页
下载文档到电脑,查找使用更方便 还剩页未读,继续阅读>>
1 / 28
此文档下载收益归作者所有 下载文档
  • 版权提示
  • 文本预览
  • 常见问题
  • 重叠IO模型PreparedbyShing(Remark:ModifiedbyZero)2种类型OverlappedIO事件通知模型后来,微软通过调查发现,老陈不喜欢上下楼收发信件,因为上下楼其实很浪费时间于是微软再次改进他们的信箱新式的信箱采用了更为先进的技术,只要用户告诉微软自己的家在几楼几号,新式信箱会把信件直接传送到用户的家中,然后告诉用户,你的信件已经放到你的家中了!老陈很高兴,因为他不必再亲自收发信件了!OverlappedIO完成例程模型老陈接收到新的信件后,一般的程序是:打开信封-掏出信纸-阅读信件-回复信件.为了进一步减轻用户负担,微软又开发了一种新的技术:用户只要告诉微软对信件的操作步骤,微软信箱将按照这些步骤去处理信件,不再需要用户亲自拆信/阅读/回复了!老陈终于过上了小资生活!OutlineTraditionalBlockingI/OOverlappedI/OEventObjectSignalingAlertableI/OTraditionalBlockingI/OTimeRequired=A+B+C+DMaxRate=PacketSize/TimeRequiredDoSomeProcessingRecv()WaitforPacketMoveDatatoUserBufferCallLowerLayerReceiveRoutineABCDApplicationOSOverlappedI/OWhenusingoverlappedI/O,theI/OoperationwillruninthebackgroundWhiletheI/Ooperationrunsinthebackground,theapplicationcandosomeotherprocessingWhentheI/Ooperationcompletes,theapplicationisnotifiedTherearemultiplemechanismsfornotifyingtheapplicationthatanI/Ooperationhasbeencompleted:EventObjectSignalingAlertableI/OOverlappedI/OAdvantagesNon-blockingUseapplicationbufferstoreceivedatadirectlyAllowpostingmultiplereceivecallsOverlappedI/OCreate Overlapped SocketUseWSASocket()insteadofsocket()Usenormalbind(),accept(),connect()etcOverlappedI/OSend&Receive DataForTCP,useWSASend()WSARecv()ForUDP,useWSASendTo()WSARecvFrom()OverlappedI/OReceiveImportantparametersforWSARecvandWSARecvFrom:SocketArrayofWSABUFstructuresNumberofelementsinWSABUFarrayWSAOVERLAPPEDstructurePointertoI/Ocompletionroutine(usedforalertableI/O)OverlappedI/OReceiveThereturnvalueDoesnotreturnthenumberofbytesreceived.Onlytellyouitsuccessorerror.SOCKET_ERRORmaybereturnedeventherewasnoerror.UseWSAGetLastError()tocheck,iferrorcodeisWSA_IO_PENDING,itmeansthereisnoerror!OverlappedI/OWSABUFThedefinitionofbufferforoverlappedI/OlenThelengthofbufferHavetobefilledinadvancebufThememoryspacethatactuallyholdthedatatypedef struct _WSABUF u_long len;char FAR*buf;WSABUF,*LPWSABUF;OverlappedI/OWSAOVERLAPPED structureAmeanfornotificationtypedef struct _WSAOVERLAPPED DWORD Internal;DWORD InternalHigh;DWORD Offset;DWORD OffsetHigh;WSAEVENT hEvent;WSAOVERLAPPED,*LPWSAOVERLAPPED;hEventFunctioncallreturnsimmediately,somemechanismsareneededtodeterminethestatusandthecompletionoftherequestUsedineventobjectnotificationOverlappedI/OThe Model-Use of Event ObjectProcessPreviousDataWSARecv()WaitforPacketCallLowerLayerReceiveRoutinewithApp.BufferApplicationOSWaitforCompletionEventNeedtoFigureOutwhichBufferisBeingFilled(orReturned)OverlappedI/OEvent Object NotificationCreateaneventobjectSimilartoMutexandSemaphore,eventobjectsalsohavesignaledornonsignaledstatePassthisobjecttohEventoftheWSAOVERLAPPEDstructureToknowwhentheI/OoperationcompleteWSAWaitForMultipleEvents()ToretrievetheresultsofoverlappedoperationsWSAGetOverlappedResult()ResettheeventobjecttononsignaledstateWSAResetEvent()TofreeresourcesoccupiedbytheeventobjectWSACloseEvent()WSAEVENT WSACreateEvent(void);实例1./writebylarry2./2009-8-203./ThisisaserverusingoverlappedIO(eventnotify).4.#includestdafx.h5.#include6.#include7.#pragmacomment(lib,ws2_32.lib)8.#definePORT51509.#defineMSGSIZE102410.typedefstruct11.12.WSAOVERLAPPEDoverlap;13.WSABUFBuffer;14.charszMessageMSGSIZE;15.DWORDNumberOfBytesRecvd;16.DWORDFlags;17.PER_IO_OPERATION_DATA,*LPPER_IO_OPERATION_DATA;18.intg_iTotalConn=0;19.SOCKETg_CliSocketArrMAXIMUM_WAIT_OBJECTS;20.WSAEVENTg_CliEventArrMAXIMUM_WAIT_OBJECTS;21.LPPER_IO_OPERATION_DATAg_pPerIoDataArrMAXIMUM_WAIT_OBJECTS;22.DWORDWINAPIWorkerThread(LPVOIDlpParam);23.voidCleanup(intindex);24.1.代码结构存在什么问题?2.代码哪些可以优化?25.intmain(intargc,char*argv)26.27.WSADATAwsaData;28.SOCKETsListen,sClient;29.SOCKADDR_INlocal,client;30.DWORDdwThreadId;31.intiAddrSize=sizeof(SOCKADDR_IN);32./Initializewindowssocketlibrary33.WSAStartup(0 x0202,&wsaData);34./Createlisteningsocket35.sListen=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);36./Bind37.local.sin_family=AF_INET;38.local.sin_addr.S_un.S_addr=htonl(INADDR_ANY);39.local.sin_port=htons(PORT);40.bind(sListen,(sockaddr*)&local,sizeof(SOCKADDR_IN);41./Listen42.listen(sListen,3);43./Createworkerthread44.CreateThread(NULL,0,WorkerThread,NULL,0,&dwThreadId);45.while(TRUE)46.47./Acceptaconnection48.sClient=accept(sListen,(sockaddr*)&client,&iAddrSize);49.printf(Acceptedclient:%s:%dn,inet_ntoa(client.sin_addr),ntohs(client.sin_port);50.g_CliSocketArrg_iTotalConn=sClient;51./AssociateaPER_IO_OPERATION_DATAstructure52.g_pPerIoDataArrg_iTotalConn=(LPPER_IO_OPERATION_DATA)HeapAlloc(53.GetProcessHeap(),54.HEAP_ZERO_MEMORY,55.sizeof(PER_IO_OPERATION_DATA);56.g_pPerIoDataArrg_iTotalConn-Buffer.len=MSGSIZE;57.g_pPerIoDataArrg_iTotalConn-Buffer.buf=g_pPerIoDataArrg_iTotalConn-szMessage;58.g_CliEventArrg_iTotalConn=g_pPerIoDataArrg_iTotalConn-overlap.hEvent=WSACreateEvent();59./Launchanasynchronousoperation60.WSARecv(g_CliSocketArrg_iTotalConn,61.&g_pPerIoDataArrg_iTotalConn-Buffer,62.1,63.&g_pPerIoDataArrg_iTotalConn-NumberOfBytesRecvd,64.&g_pPerIoDataArrg_iTotalConn-Flags,65.&g_pPerIoDataArrg_iTotalConn-overlap,66.NULL);67.g_iTotalConn+;68.69.closesocket(sListen);70.71.WSACleanup();72.return0;73.74.DWORDWINAPIWorkerThread(LPVOIDlpParam)75.76.intret,index;77.DWORDcbTransferred;78.while(TRUE)79.80.ret=WSAWaitForMultipleEvents(g_iTotalConn,g_CliEventArr,FALSE,1000,FALSE);81.if(ret=WSA_WAIT_FAILED|ret=WSA_WAIT_TIMEOUT)82.83.continue;84.85.index=ret-WSA_WAIT_EVENT_0;86.WSAResetEvent(g_CliEventArrindex);87.WSAGetOverlappedResult(g_CliSocketArrindex,88.&g_pPerIoDataArrindex-overlap,89.&cbTransferred,90.TRUE,91.&g_pPerIoDataArrg_iTotalConn-Flags);92.if(cbTransferred=0)93.94./Theconnectionwasclosedbyclient95.Cleanup(index);96.97.else98.99./g_pPerIoDataArrindex-szMessagecontainstherecviveddata100.g_pPerIoDataArrindex-szMessagecbTransferred=0;101.send(g_CliSocketArrindex,g_pPerIoDataArrindex-szMessage,cbTransferred,0);102./Launchanotherasynchronousoperation103.WSARecv(g_CliSocketArrindex,104.&g_pPerIoDataArrindex-Buffer,105.1,106.&g_pPerIoDataArrindex-NumberOfBytesRecvd,107.&g_pPerIoDataArrindex-Flags,108.&g_pPerIoDataArrindex-overlap,109.NULL);110.111.112.113.return0;114.115.voidCleanup(intindex)116.117.closesocket(g_CliSocketArrindex);118.WSACloseEvent(g_CliEventArrindex);119.HeapFree(GetProcessHeap(),0,g_pPerIoDataArrindex);120.if(indexBuffer.len=MSGSIZE;lpPerIOData-Buffer.buf=lpPerIOData-szMessage;lpPerIOData-sClient=g_sNewClientConnection;WSARecv(lpPerIOData-sClient,&lpPerIOData-Buffer,1,&lpPerIOData-NumberOfBytesRecvd,&lpPerIOData-Flags,&lpPerIOData-overlap,CompletionRoutine);g_bNewConnectionArrived=FALSE;SleepEx(1000,TRUE);return0;voidCALLBACKCompletionRoutine(DWORDdwError,DWORDcbTransferred,LPWSAOVERLAPPEDlpOverlapped,DWORDdwFlags)LPPER_IO_OPERATION_DATAlpPerIOData=(LPPER_IO_OPERATION_DATA)lpOverlapped;if(dwError!=0|cbTransferred=0)/Connectionwasclosedbyclientclosesocket(lpPerIOData-sClient);HeapFree(GetProcessHeap(),0,lpPerIOData);elselpPerIOData-szMessagecbTransferred=0;send(lpPerIOData-sClient,lpPerIOData-szMessage,cbTransferred,0);/Launchanotherasynchronousoperationmemset(&lpPerIOData-overlap,0,sizeof(WSAOVERLAPPED);lpPerIOData-Buffer.len=MSGSIZE;lpPerIOData-Buffer.buf=lpPerIOData-szMessage;WSARecv(lpPerIOData-sClient,&lpPerIOData-Buffer,1,&lpPerIOData-NumberOfBytesRecvd,&lpPerIOData-Flags,&lpPerIOData-overlap,CompletionRoutine);完成例程小结1.用完成例程来实现重叠I/O比用事件通知简单得多。

    2.调用SleepEx使线程处于一种可警告的等待状态,以使得I/O完成后CompletionROUTINE可以被内核调用如果辅助线程不调用SleepEx,则内核在完成一次I/O操作后,无法调用完成例程(因为完成例程的运行应该和当初激活WSARecv异步操作的代码在同一个线程之内)3.在调用WSARecv时,参数lpOverlapped实际上指向一个比它大得多的结构这样,在完成例程中通过参数lpOverlapped拿到的不仅仅是WSAOVERLAPPED结构,还有后边尾随的包含客户端套接字和接收数据缓冲区等重要信息这样的C语言技巧在我后面介绍完成端口的时候还会使用到还有什么模型?IOCP模型(对应书上第4章)微软信箱似乎很完美,老陈也很满意但是在一些大公司情况却完全不同!这些大公司有数以万计的信箱,每秒钟都有数以百计的信件需要处理,以至于微软信箱经常因超负荷运转而崩溃!需要重新启动!微软不得不使出杀手锏.微软给每个大公司派了一名名叫CompletionPort的超级机器人,让这个机器人去处理那些信件!。

    点击阅读更多内容
    卖家[上传人]:无极剑圣
    资质:实名认证