IOCP完成埠與長連線通訊
阿新 • • 發佈:2019-01-27
最近在寫一個通訊代理程式的時候使用了IOCP通訊模型,幾年前也使用過IOCP,不過當時的程式是基於短連線的,而這次是長連線的,寫這個程式的過程中我覺得主要有以下幾點值得注意:
1、整個程式的架構:程式由一個Accept執行緒,n個工作者執行緒,1個執行緒池管理執行緒,n個業務處理執行緒構成。Accept執行緒接收客戶端連線並投遞WSARecv重疊操作,工作者執行緒中通過GetQueuedCompletionStatus阻塞收取資料,收取請求資料後將資料放入佇列,然後再投遞一個WSARecv重疊操作至GetQueuedCompletionStatus阻塞呼叫,如果是短連線的話,此處就不需要再投遞WSARecv重疊操作了,直接呼叫GetQueuedCompletionStatus收取另一個客戶端連線傳送過來的資料就可以了。我剛開始也忽略了這一點,導致程式每次只能收取客戶端的第一個請求,後面就再也收不到了。
2、可以利用WSARecv和recv結合來完成"包頭+資料體"形式的請求包的收取,在我們的程式中,資料體的長度是由包頭中的某個引數來指定的,而WSARecv是非阻塞呼叫的(容易導致包頭和資料體被不同的工作者執行緒收取,重新組裝請求很麻煩),在收取這樣的請求包時很不方便,於是我先利用WSARecv來收取包頭,然後再根據包頭中指定的長度呼叫recv阻塞收取相應長度的資料體,這樣雖然效能上帶來了一些損失,不過因為組裝請求包方面簡單很多,耗用的資源更少,總體來看也是值得的。
3、以後再接著補充...