完成埠的乙個例子

2021-04-21 01:47:42 字數 2516 閱讀 6157

來自微軟的完成埠例子,就講解一下它的使用套路吧

反正程式設計這個玩意,只要用過,自然就知道什麼回事,一次不會再看一次,學習這個玩意,無他,勤奮而已。

奢談效率等等,那只是孰能生巧上的功夫。

這個例子是在console下的例子,算是乙個echo伺服器吧,

跑起來後將在5150埠監聽,一旦有個埠連線上來,發個資料給服務埠,它就echo回資料給那個埠. 直到那個連線中斷.

完成埠,其實理解成乙個通道或管子就可以了,和管道也差不了多少,不過可以實現非同步處理罷了,

你這邊往管子裡丟資料,通過getqueuedcompletionstatus來查管子那頭出資料沒,出了就處理,這個管子就是通過乙個自定義有點特殊的結構來寫入或讀出資料而已.

那個完成埠,其實就相當是標識那個資料塊的控制代碼,

//下面請看例子

#i nclude

#i nclude

#i nclude

#define port 5150

#define data_bufsize 8192

#pragma comment(lib, "ws2_32")

typedef struct                        //這個玩意就是灌資料,取資料的乙個自定義資料結構

typedef struct

per_handle_data, * lpper_handle_data;

dword winapi serverworkerthread(lpvoid completionportid);

void main(void)

////完成埠的建立得搞2次,這是第一次呼叫,至於為什麼?我問問你

//if ((completionport = createiocompletionport(invalid_handle_value, null, 0, 0)) == null)

//老套子api,不談也罷

getsysteminfo(&systeminfo);

//發現2個cpu,那就開個雙倍的執行緒跑吧

for(i = 0; i < systeminfo.dwnumberofprocessors * 2; i++)

closehandle(threadhandle);

}internetaddr.sin_family = af_inet;

internetaddr.sin_addr.s_addr = htonl(inaddr_any);

internetaddr.sin_port = htons(port);

if (bind(listen, (psockaddr) &internetaddr, sizeof(internetaddr)) == socket_error)

if (listen(listen, 5) == socket_error)

//// 監聽埠開啟,就開始在這裡迴圈,一有socket連上,wsaaccept就建立乙個socket,

// 這個socket 又和完成埠聯上,

//// 嘿嘿,完成埠第二次呼叫那個create***函式,為什麼,留給人思考思考可能更深刻,

// 反正這套路得來2次,

// 完成埠completionport和accept socket掛起來了,

//while(true)

if ((perhandledata = (lpper_handle_data) globalalloc(gptr, sizeof(per_handle_data))) == null)

perhandledata->socket = accept;

////把這頭和完成埠completionport連起來

//就像你把漏斗接到管子口上,開始要灌資料了

//if (createiocompletionport((handle) accept, completionport, (dword) perhandledata,

0) == null)

////清管子的資料結構,準備往裡面灌資料

//if ((periodata = (lpper_io_operation_data) globalalloc(gptr,sizeof(per_io_operation_data))) == null)

// 檢查資料傳送完了嗎

if (bytestransferred == 0)

globalfree(perhandledata);

globalfree(periodata);

continue;

}    

////看看管子裡面有資料來了嗎?=0,那是剛收到資料

//if (periodata->bytesrecv == 0)

else   //來了,

//// 資料沒發完?繼續send出去

//if (periodata->bytesrecv > periodata->bytessend)

{periodata->databuf.len = data_bufsize;

periodata->databuf.buf = periodata->buffer;

LineDDA的乙個例子

unit unit1 inte ce uses windows,messages,sysutils,variants,classes,graphics,controls,forms,dialogs,extctrls,stdctrls,buttons type tfmmain class tform ...

SQL GROUP CONCAT的乙個例子

我有乙個這樣的資料庫 user info 現在有乙個需求是把這樣 9 條記錄按照 username 來 group 成3條記錄 目標 shu female 201 lee male 202 yuki female 181 如果用select from user info group by usern...

explode的乙個例子

select level as level,explode split 1,2,3 as value 可以生成結果 level value level 1 level 2 level 3 lateral view 1.lateral view 用於和udtf函式 explode,split 結合來使...