BOOL GetQueuedCompletionStatus(
HANDLE CompletionPort, // 完成端口句柄
LPDWORD lpNumberOfBytes, // 傳送數據字節數
PULONG_PTR lpCompletionKey, // 完成鍵
LPOVERLAPPED * lpOverlapped, // 重疊結構體
DWORD dwMilliseconds // 超時毫秒數
);
GetQueuedCompletionStatus函數中有兩個參數lpCompletionKey和lpOverlapped
lpCompletionKey被稱爲完成鍵,傳遞的數據被稱爲單句柄數據,數據應該是與每個socket句柄對應
lpOverlapped被稱爲重疊結構體,傳遞的數據被稱爲單IO數據,數據應該與每次的操作WSARecv、WSASend等相對應
兩個參數都可以用來傳遞任意數據,包括操作類型、緩衝buffer、套接字等等,網上下載的例子中把buffer放在哪個裏面的都有,有的人喜歡全放到一個裏面,難免讓新接觸IOCP的coder們疑惑究竟應該放在哪個裏面好一些。
個人認爲理論上哪個都是可以的,但最好還是根據上面所說的句柄和數據分開傳遞。比如一個只需要connect驗證服務器是否開啓的服務,是不需要buffer的。
通過對IOCP的深入理解,發現buffer不宜放在完成鍵中。首先猜測下爲什麼有人放完成鍵中,可能是對IOCP模型理解不夠深入,也可能因爲這樣做每個socket句柄只需要一個buffer就可以了,不用每個IO都申請buffer。但是在實際應用中,一個socket可能有多個IO請求在隊列中,這時每個IO請求都需要獨立的buffer存儲數據。
注:以上內容純屬個人理解,如有不對的地方請高手指正!