在win32平台上最有效率的io模型,莫過於完成埠了。csdn上到處都是關於完成埠的問題。在ace中對win32平台的完成埠有著非常好的封裝。ace中前攝式框架的win32實現就是使用的完成埠。我們先來看看這個框架有哪些組成部分。
ace_proactor 前攝器,真怪異的名字。叫非同步事件分配者多好啊。
ace_service_handler 事件處理器。處理所有非同步操作的結果。
ace_asynch_accept 非同步連線接受器。用來監聽來自客戶的連線請求。
ace_asynch_read_stream 非同步讀取器。發起非同步讀操作的請求。
ace_asynch_write_stream 非同步寫入器。發起非同步寫操作的請求。
嗯!東西差不多齊了。不要看到上面的東西就害怕,其實很簡單,請相信我。
我們先來講一下,執行的流程。
首先,我們會使用accept的open()方法,,監聽乙個埠。
ace_inet_addr localhost;
localhost.set(8888,「127.0.0.1「);
acceptor.open(localhost);
此時,當有客戶端的連線請求到達時,前攝器會自動的呼叫acceptor 的make_handle()方法,來建立乙個事件處事器,處理這個連線的使用者。
//我定義的使用者事件處理器類,繼承於ace_service_handler
ctg_gs_user_handler *puser_handler;
//使用ace的建立巨集,分配乙個空間。
ace_new_noreturn(puser_handler,ctg_gs_user_handler(this));
if (puser_handler == null)
return puser_handler;
前攝器通過呼叫這個方法後,得到了puser_handler的控制代碼,並將socket與這個控制代碼定到一起。
隨後,前攝器會緊接著呼叫 ctg_gs_user_handler的open方法。方法的原型如下:
void ace_service_handler::open
( ace_handle
new_handle,
ace_message_block &
message_block
)這是ace_service_handler的乙個虛方法,需要我們來繼承,以完成我們的事件處理器的一些初始化準備。
上面我們定義的ctg_gs_user_handler類,是乙個很重要的組成部分,處理絕大部分的io事件。他繼承於ace_service_handler,實現了以以下的三個方法。
virtual void handle_time_out(const ace_time_value &tv,const void *p);
定時器**函式
virtual void handle_read_stream(const ace_asynch_read_stream::result &result);
讀操作**函式
virtual void handle_write_stream(const ace_asynch_write_stream::result &result);
寫操作**函式
比如,當我們發起乙個非同步的讀操作時。
//reader_是乙個上面提到的非同步讀取器
reader_.read(*mblk_,sizeof(ccmdmessagehead));
當讀操作完成,或部分完成時,會**handle_read_stream方法。
我們要做如下的處理。
void ctg_gs_user_handler::handle_read_stream(const ace_asynch_read_stream::result &result)
else if (result.bytes_transferred() < result.bytes_to_read())
//如果沒有接收完成,繼續接收。
reader_.read(*mblk_,result.bytes_to_read()-result.bytes_transferred());
else if (mblk_->length() == sizeof(ccmdmessagehead))
ace_new_noreturn
(mblk_, ace_message_block (ace_default_cdr_bufsize));
ace_cdr::mb_align (mblk_);
reader_.read (*mblk_, sizeof(ccmdmessagehead));
}else
} else
ace_new_noreturn(mblk_, ace_message_block (ace_default_cdr_bufsize));
ace_cdr::mb_align (mblk_);
reader_.read (*mblk_, sizeof(ccmdmessagehead));
}return;
}這樣,我們就完整地接到了乙個訊息。這其中可能有些型別和變數你還不太理解,我以後會慢慢告訴你的,廣告之後馬上回來。
ACE中使用完成埠
使用ace中的proactor的話,會要比我們使用我們直接寫的要來得簡單。在說proactor之前我們需要了解windows裡的完成埠的工作原理。完成埠是winnt核心裡的乙個框架。我們可以為我們的一些非同步的操作 新建乙個完成埠,然後這個完成埠會有幾個工作執行緒來處理。我們 可以將socket,或...
完成埠實現echo tcp server
include stdio.h include winsock2.h pragma comment lib,ws2 32.lib define port 5150 define data bufsize 8192 typedef struct char buffer data bufsize int...
C I O完成埠的實現
在 vc 中我幾乎每乙個 windows service 都是採用 i o完成埠。至於在 c 中如何使用 i o完成埠,一直很少見人提及。william kennedy 的三篇文章 iocp thread pooling in c 對實現這種機制很有幫助,唯一美中不足的是,它只能把 int數值壓入完...