本文作者:sodme
本文出處:http://blog.csdn.net/sodme
聲明:本文可不經作者同意,任意被轉載、引用、複制,但任何對本文的引用都必須注明本文作者,出處以及本行聲明資訊。謝謝。
作為WIN平台下同時管理數千個連接配接的最為高效的網絡模型,完成端口已經被越來越多的人認識和熟悉。通常情況下,一種經典的完成端口使用模式是:
(1)建立完成端口,并在指定端口開始監聽;
(2)建立接受連接配接線程,用accept或acceptEx接受用戶端連接配接;
(3)建立工作者線程,處理用戶端的資料收發。
衆所周知,CreateIoCompletionPort函數,有兩個作用,一是“建立”一個完成端口,二是将一個socket與已經建立的完成端口句柄相“綁定”,綁定之後,基于該socket的收、發、斷開等事件都可以被完成端口感覺。一般情況下,較為正常的思維狀态下,CreateIoCompletionPort的綁定是選在accept函數執行以後或acceptEx函數完成之時與套接字相綁定。但是,這并不說明CreateIoCompletionPort函數就不能進行其它形式的綁定。
事實上,CreateIoCompletionPort關心的隻是一個套接字,它并不關心這個套接字到底是通過accept而來的,還是用來connect的。也就是說,它并不關心目前的這個socket是用于接受用戶端連接配接的,還是用來連接配接其它伺服器的。那就是說,CreateIoCompletionPort函數,也可以用來綁定一個連接配接到其它伺服器的用戶端socket。
這個問題的提出,是我在設計網關伺服器時。
網關伺服器,承擔的主要工作就是兩個:向内,負責用戶端資料包的分發;向外,負責把内部伺服器所有的傳回資料包統一通過網關發送出去。網關伺服器上,我建立了兩個IOCP,一個用來向外接受玩家與網關的資料交換,另一個用來與内部的伺服器進行資料轉發。由于本人較懶,是以想在内部的那個伺服器上,也采用IOCP模型來作。
在網關上負責向内部伺服器提供資料轉發的這個IOCP,必須要能正确識别哪一個内部伺服器使用的是哪一個套接字。這樣,内部伺服器與網關伺服器之間的套接字确認就有兩種方式。一種方式,是由内部伺服器連接配接到網關伺服器上,随後向網關伺服器發送一個注冊包,告訴網關伺服器目前的這個socket是哪個内部伺服器;另一種方式,是由網關伺服器先建立若幹個指定的socket,然後用這些socket去連接配接指定類型的内部伺服器。前面,我已經說過,IOCP可以綁定的套接字,不僅是可以被accept來的套接字,也可以是connect其它伺服器的套接字。是以,我選用了後一種方式。這樣在網關伺服器對内的IOCP的邏輯處理上,就少了一項判定和一個包的邏輯解析。當網關流量非常巨大時,每節省一項判定或一種分支,效率和資源都會得到更有效的利用,高性能從哪裡來?就是從這樣的一點一滴的改進中來。到目前為止,我能測試到的網關伺服器流量上限是每秒10M到12M,據說,區域網路的某些HUB給每台機子的帶寬隻分了10M左右的出口帶寬,是以,我無法确定如果把區域網路的交換機換成電信級的,資料交換量會不會有一個更大的提高,不久,公司會進一個這樣的電信級交換機,到時可以作進一步的測試。
過段時間,我會在我的BLOG(http://blog.csdn.net/sodme)上公布我的IOCP底層通信模型的架構設計以及一個通用的高性能伺服器模型架構,希望能與各位同仁共同研究高性能伺服器研發問題。