SOCKET重叠I/O模型
1重叠模型的优点
1可以运行在支持Winsock2的所有Windows平台,而不像完成端口只支持NT系统
2比起阻塞,select,WSAAsyncSelect以及WSAEventSelect等模型,重叠I/O(Overlapped I/O)模型使应用程序能达到更加系统性能
因为他和其他4种模型不同的是,使用重叠模型的应用程序通知缓冲区收发系统直接使用数据,也就是说,如果应用程序
投递了一个10kb大小的缓冲区来接收数据,而数据已经到达套接字,则将该数据直接拷贝到投递的缓冲区,
而4种模型中,数据达到并拷贝到单套接字接收缓冲区,此时应用程序会被告知可以读入的容量,当应用程序调用
接收函数之后,数据才从单套接字缓冲区拷贝应用程序到缓冲区,差别就体现了。
2重叠模型的基本原理
重叠模型是让应用程序使用重叠数据结构(WSAOVERLAPPED),一次投递一个或多个Winsock I/O请求,针对这些提交的
请求,在他们完成之后,应用程序会收到通知,于是就可通过自己的代码来处理这些数据了。
使用事件通知的方法来实现重叠IO模型,基于事件的话,就要求将Win事件与WSAOVERLAPPED结构关联在一起,
使用重叠结构,常用的send,sendto,recv,recvform也被WSASend,WSARecv等替换掉,
OVERLAPPER SOCKET(重叠Socket)上进行重叠发送的操作,(简单的理解就是异步send,recv)
他们的参数中都有一个Overlapped参数,就是说所有的重叠Socket都要绑定到这个重叠结构体上,
提交一个请求,其他的事情就交给重叠结构去操心, 而其中重叠结构要与Windows事件绑定在一起,
在样,我们调用完WSARecv后.等重叠操作完成,就会有对应的事件来同意我们操作完成,
2重叠模型的基础知识
typedefstruct_OVERLAPPED{ULONG_PTRInternal;ULONG_PTRInternalHigh;union{struct{DWORDOffset;DWORDOffsetHigh;}DUMMYSTRUCTNAME;PVOIDPointer;}DUMMYUNIONNAME;HANDLEhEvent;//我们只要关注这个参数,用来关联事件的}OVERLAPPED,*LPOVERLAPPED;
2WSARecv系列函数
在重叠模型中,接收数据就要靠他了,他的参数也比recv多定义是这样的:
intWSArecv(SOCKETs,//投递这个操作的套接字LPWSABUFlpBuffer,//接收缓冲区,与Recv函数不同LPDWORDlpNumberOfBytesRecvd,//如果接收操作立即完成,这里会返回函数调用LPDWORDlpFlags,//默认为0LPWSAOVERLAPPERlpOverlapper,//绑定的重叠结构LPWSAOVERLAPPER_COMPLETION_ROUTINElpCompletionRoutine//一个回调);返回值:WSA_IO_PENDING:常见返回值,说明WSARecv操作成功,但是I/O材质没完成,所以需要绑定一个事件来通知
3WSAWaitForMultipleEvents函数
等待某个事件触发的函数,我们需要事件通知我们完成重叠操作,所以需要用到这个参数。
这个函数只能有WSA_MAXIMUM_WAIT_EVENTS对象定义的一个最大值,是64,就是他只能等待64个事件
如果决的小了,就要创建额外的线程,或线程池。
DWORDWSAWaitForMultipleEvents(DWORDcEvents,//等候事件的总数量constWSAEVENT*lphEvents,//事件数组的指针BOOLfWaitAll,//如果设置为TRUE则事件中所有的事件被传信才返回,FALSE是当有事件立即返回DWORDdwTimeout,//超时时间,如果超时,函数会返回WSA_WAIT_TIMEOUT//如果设置为0,函数会立即返回//如果设置为WSA_INFINITE只有在某一个事件被传信后才会返回BOOLfAlertable)//默认用FALSE返回值:WSA_WAIT_TIMEOUT:最常见的返回值,我们需要做的就是继续等待WSA_WAIT_FAILED:出现了错误,请检查cEvents和lphEvents两个参数是否有效
4WSAGetOverlappedResult函数
既然通过WSAWaitForMultipleEvents函数来得到重叠操作的结果,那我们也需要一个函数来查询
一下重叠操作的结果, 这个函数不需要关注返回值
BOOLWSAGetOverlappedResult(SOCKETs,//SOCKET,不用说了LPWSAOVERLAPPEDlpOverlapped,//这里是我们想要查询结果的那个重叠结构的指针LPDWORDlpcbTransfer,//本次重叠操作的实际接收(或发送)的字节数BOOLfWait,//设置为TRUE,除非重叠操作完成,否则函数不会返回//设置FALSE,而且操作仍处于挂起状态,那么函数就会返回FALSELPDWORDlpdwFlags//指向DWORD的指针,负责接收结果标志第二个参数是输出的第三个参数也是输出的,就是你接收的字节数为0那说明对方关闭socket了
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。