AcceptEx與完成埠(IOCP)結合例項

2021-09-10 06:40:19 字數 2921 閱讀 6192

前言在windows平台下實現高效能網路伺服器,iocp(完成埠)是唯一選擇。編寫網路伺服器面臨的問題有:1 快速接收客戶端的連線。2 快速收發資料。3 快速處理資料。本文主要解決第乙個問題。

acceptex函式定義

bool acceptex(

socket slistensocket,

socket sacceptsocket,

pvoid lpoutputbuffer,

dword dwreceivedatalength,

dword dwlocaladdresslength,

dword dwremoteaddresslength,

lpdword lpdwbytesreceived,

);

為什麼要用acceptex

傳統的accept函式能滿足大部分場景的需要;但在某些極端條件下,必須使用acceptex來實現。兩個函式的區別如下:

1)accept是阻塞的;在乙個埠監聽,必須啟動乙個專用線程呼叫accept。當然也可以用迂迴的方式,繞過這個限制,處理起來會很麻煩,見文章單執行緒實現同時監聽多個埠。acceptex是非同步的,可以同時對很多埠監聽(監聽埠的數量沒有上限的限制)。採用迂迴的方式,使用accept監聽,乙個執行緒最多監聽64個埠。這一點可能不是acceptex最大優點,畢竟同時對多個埠監聽的情況非常少見。

2)acceptex可以返回更多的資料。a)acceptex可以返回本地和對方ip位址和埠;而不需要呼叫函式getsockname和getpeername獲取網路位址了。b)acceptex可以再接收到一段資料後,再返回。這種做法有利有弊,一般不建議這樣做。

3)acceptex是先準備套接字(socket)後接收。為了應對突發的連線高峰,可以多次投放acceptex。accept是事後建立socket,就是tcp三次握手完成後,accept呼叫才返回,再生成socket。生成套接字是相對比較耗時的操作,accept的方式無法及時處理突發連線。對於acceptex的處理方式為建議做如下處理:乙個執行緒負責建立socket,乙個執行緒負責處理acceptex返回。

以上僅僅通過文字說明了acceptex的特點。下面通過具體**,逐一剖析。我將acceptex的處理封裝到類iocpacceptex中。編寫該類時,盡量做到高內聚低耦合,使該類可以方便的被其他模組使用。

iocpacceptex外部功能說明

class iocpacceptex

#define post_accept 1

//使用iocpacceptex類,必須實現該介面。接收客戶端的連線

class iacceptcallback

;

該類的呼叫函式很簡單,對外介面也很明確。說明該類的職責很清楚,這也符合單一職責原則。

實現步驟說明

acceptex不但需要與監聽埠繫結,還需要與完成埠繫結。所以程式的第一步是建立完成埠:

a)建立完成埠

m_hiocp = createiocompletionport(invalid_handle_value, null, null, 0);

if (m_hiocp == null)

return false;

b)監聽埠建立與繫結

//生成套接字

if (serversocket == invalid_socket)

//繫結

sockaddr_in addr;

memset(&addr, 0, sizeof(addr));

addr.sin_family = af_inet;

addr.sin_addr.s_addr = inaddr_any ;

addr.sin_port = htons(port);

if (bind(serversocket, (sockaddr *)&addr, sizeof(addr)) != 0)

//啟動監聽

if (listen(serversocket, somaxconn) != 0)

//監聽埠與完成埠繫結

if (createiocompletionport((handle)serversocket, m_hiocp, (ulong_ptr)this, 0) == null)

c)投遞acceptex

;int iocpacceptex::newaccept(socket serversocket)

}return 1;}

acceptex是非阻塞操作,呼叫會立即返回。當有客戶端連線時,怎麼得到通知。答案是通過完成埠返回。注意有乙個步驟:監聽埠與完成埠繫結,就是serversocket與m_hiocp繫結,所以當有客戶端連線serversocket時,m_hiocp會得到通知。需要生成執行緒,等待完成埠的通知。

d)通過完成埠,獲取通知

dword dwbytestransferred;

ulong_ptr key;

bool rc;

int error;

while (m_bserverstart)

else}}

if (lpperiodata != null)

break;}}

else

}return 0;  

dword winapi iocpacceptex::acceptexthreadpool(pvoid pcontext)

** 採用完成埠是提高io處理能力的乙個途徑(廣義上講,通訊操作也是io)。為了提高io處理能力,windows提供很多非同步操作函式,這些函式都與完成埠關聯,所以這一類處理的思路基本一致。學會了acceptex的使用,可以做到觸類旁通的效果。

AcceptEx函式與完成埠的結合使用例子

這是在學 windows網路程式設計 第二版 第六章時製作的乙個例子 由於書中沒有給出簡潔的例子,本人在學這裡時就費了很多時間。下面包括了主程式部分,工作執行緒在 2 中貼出,由於 太長。本程式在vs2003編譯器編譯執行。在6.0下可能需要稍加修改。include include include ...

完成埠IO模型

iocp io完成埠 是一種伸縮性的io模型,廣泛應用於各種型別的高效能伺服器,如apache等。io完成埠,應用程式使用執行緒池處理非同步io請求的一種機制。最初設計 應用程式發出一些非同步io請求,裝置驅動把這些工作專案排序到完成埠,在完成埠上等待執行緒池便可以處理這些完成io。完成埠實際上是乙...

I O 完成埠實現

這篇文章是繼承上篇 windows 同步裝置 i o 與非同步裝置 i o 未讀過的讀者可以去看看再來看這篇文章哈。建立新的i o完成埠 i o完成可能是最複雜的windows核心物件了,為了建立乙個i o完成端 們需要呼叫createiocompletionport函式 handle winapi...