小弟刚学的IOCP,最近在看《Networking Programming for Microsoft Windows》,其中里面说道
“当与一个完成端口相关的文件句柄上启动的异步IO操作完成时,一个IO完成包就会进入到该完成端口的队列中。”
我的问题是:
1.这个完成包应该是系统自己投递到完成队列当中的,是吗?
2.对这个完成包要怎么处理?我知道要在线程里调用GetQueuedCompletionStatus函数获取完成包,但接下来呢?在这个完成包里系统是不是会设置一个参数用来指定本次完成的操作类型还是怎么回事?
看了些资料还是一头雾水啊。请各位高手不吝赐教。
“当与一个完成端口相关的文件句柄上启动的异步IO操作完成时,一个IO完成包就会进入到该完成端口的队列中。”
我的问题是:
1.这个完成包应该是系统自己投递到完成队列当中的,是吗?
2.对这个完成包要怎么处理?我知道要在线程里调用GetQueuedCompletionStatus函数获取完成包,但接下来呢?在这个完成包里系统是不是会设置一个参数用来指定本次完成的操作类型还是怎么回事?
看了些资料还是一头雾水啊。请各位高手不吝赐教。
解决方案 »
- CAsyncSocket::Bind这个函数有用吗?//Create函数不就完成了吗?ip地址 Create函数自动添加的吗?
- 图像显示
- 关于CInternetSession类打开http文件缓存问题
- 一个很基础的问题(高分)
- 大侠们救命呀,能不能告诉我如何用VC读研华PCL_813B采集到的数据,在人家现场等
- 哪位朋友有Xtreme Toolkit的汉化了的中文资源
- 怎样单击在左边的一个列表项而使右边改变控件?
- 求助!关于CBitmapButton的LoadBitmaps()。
- (在线等待)--想把一个路径包含进来,在项目->属性里怎么设?
- 请问:可以将void CALLBACK Proc1(......)在一个类中声明吗?谢谢。
- VCAPrcVidCapCallBack回调函数刷新界面
- 求助~急~关于matlab以及C语言的问题
这句话说的很好,比如 WSASend, WSARecv, 包括 CancelIO, 等等函数,都是触发IO操作,要明白IO操作就是输入输出操作。那么为什么要一个 OpCode ,以为只要是触发了IO的操作都会让 GetQueueXXX 返回,但是我们实际上只需要的是 Recv 操作,以为这个是我们关注的,而 Send 操作其实对于我们来说可能没什么用,但是如何区分,就是靠GetQueueXX的 Overlapped 这个值,其实这个值是我们传递过去的,是一个指针,WSARecv,WSASend都有这个参数,实际 GetQueue得到的这个值就是 WSARecv设置的OVERLAPPED指针,一般的方法就是将这个指针扩展下,除了标准的 overlapped 另外加一个我们需要的信息,就是所谓的 opcode 这样我们就可以判断出 getqueue 返回的到底是发送,还是接收 消息,或者其他消息。
另外一个问题:为什么完成端口效率比较高。其实完成端口的核心思想就是队列化,一般来说线程数量=处理器数量X2,也就是说,比如一般服务器是4个CPU,按每个都是双核算,就是8个核心,就是16个线程,这样,当同时的消息比较少的时候,我们只有几个线程在工作。不会占用过多的CPU,但是当网络流量很大的时候,当16个线程都在工作的时候。如果另外有请求出现,完成端口的作用就显现出来了,完成端口会将剩下的请求排成一个队列,也就是排队处理,这样在不过度消耗CPU和内存的情况下,最大效率的处理请求,这个就是完成端口。其实高级的完成端口设计实际还是使用了线程池,内存池等技术,网上有很多成熟的IOCP类,用起来很方便的,我常用的IOCP类就是自己在 gh0st 的IOCP类基础上改的,自己写着玩还行,反正我不是做服务器开发的。
ULONG_PTR Internal;
ULONG_PTR InternalHigh;
DWORD Offset;
DWORD OffsetHigh;
HANDLE hEvent;
} OVERLAPPED; Members
Internal
Not used.
InternalHigh
Not used.
Offset
File offset of the beginning of the lock range.
OffsetHigh
High order word of the byte offset of the beginning of the lock range.
hEvent
Not used. 前两个未使用,3,4 个分别表示IO操作的偏移,这个一般用在异步写文件的时候,写入文件的偏移位置HANDLE hEvent; 是最重要的,就是一个 Event 句柄,IO操作完成以后系统会 SetEvent 来设置这个 event 返回,一般通过等待WaitForSingleObject(ol->hEvent, ...); 可以等待IO操作完成。一般系统内只要涉及到IO异步的都会用到这个结构体。你不需要对他进行什么操作,因为函数需要传递一个 overlapped 结构的指针,而 GetQueue 收到的也是这个指针,那么就可以通过这个指针,传递一些我们需要的信息。