socket模型之重疊i/o模型
這幾天一直在看關於socket程式設計的幾種非同步程式設計,我覺得關於重疊i/o模型的一些基本知識,我有必要記下來。
在實際的程式設計過程中,我們需要按照下面幾步來編寫我們的socket重疊模型的程式:一、在伺服器端
1、首先初始化socket套接字。由於編寫非同步套接字所需要的函式包含在標頭檔案winsock2.h中,所以我們首先需要包含該標頭檔案。另外還要鏈結ws2_32.lib庫,這樣我們才能夠使用非同步套接字的一些函式。
例如:
1wsadata wsadata;
2int nret = ::wsastartup(makeword(2, 2), &wsadata);
3if(nret != 0)4
2、然後我們就可以建立乙個套接字物件用於監聽。
1 socket slisten = ::socket(af_inet, sock_stream, 0);3、繫結該套接字到sockaddr_in結構
1 ushort nport = 6000;2sockaddr_in sin;
3 sin.sin_family =af_inet;
4 sin.sin_port =::htons(nport);
5 sin.sin_addr.s_un.s_addr =::htonl(inaddr_any);
6if(::bind(slisten, (sockaddr*)&sin, sizeof(sin)) ==socket_error)
7
4、然後就可以監聽來自客戶端的套接字了。
1if(::listen(slisten, 5) ==socket_error)
2
5、接下來我們就可以接收客戶端的連線了。
1sockaddr_in clientaddr;
2int nlen = sizeof
(clientaddr);
3 socket sockaccept = ::accept(slisten, (sockaddr*)&clientaddr, &nlen);
4if(sockaccept ==socket_error)
5
6、由於要用到重疊模型來提交我們的操作,所以原來的recv、send、sendto、recvfrom等函式都要被替換為wsarecv、wsasend、wsasendto、wsarecvfrom函式來代替。例如:當我們要接收從客戶端發來的訊息時,我們可以按照下面的步驟來接收資訊。
1#define data_buffsize 4096
2 wsaevent eventarray[wsa_maximum_wait_events]; //
定義乙個事件陣列,最大容量為wsa_maximum_wait_events
3 socket socketarray[wsa_maximum_wait_events]; //
定義乙個socket陣列,最大容量為wsa_maximum_wait_events
定義乙個重疊模型結構陣列,
5 wsabuf databuf; //
定義乙個wsabuf結構
6int ntotalevent = 0; //
記錄事件的總數
7char
buffer[data_buffsize];
8 zeromemory(buffer, sizeof
(buffer));
9 eventarray[ntotalevent] = ::wsacreateevent(); //
利用wsacreateevent()函式來建立乙個事件物件並賦值給eventarray[ntotalevent]
10 databuf.buf = buffer; //
給wsabuf結構賦值
11 databuf.len =data_buffsize;
將建立的事件物件和重疊結構繫結起來,
14 socketarray[ntotalevent] =sockaccept;
15 dword dwbytes = 0
;16 dword dwflags = 0;17
1825 }
7.當我們做完上面的工作後,下面我們就可以呼叫wsawaitformultipleevents()函式來等待事件的發生了。若有事件發生則返回事件的索引,但我們應該減去乙個常數wsa_wait_event_0,才能得到在eventarray陣列中的索引。
1int nindex =::wsawaitformultipleevents(ntotalevent, eventarray, false, wsa_infinite, false);
2if(nindex ==wsa_wait_falied)
37 nindex = nindex -wsa_wait_event_0;
8 ::wsaresetevent(eventarray[nindex]); //
當事件被觸發時,應該重置該事件物件
由於第三個引數我們設為false,那麼當任意一件事件發生時,該函式就會返回,那麼當同時有幾件事件發生時,後面發生的事件就得不到處理,因此,我們可以迴圈for(int i = nindexl; i < ntotalevent; i++)來對後面的事件進行處理。
1 dword dwtranslatebytes = 0;2 dword dwflags = 0
;3 socket & sockettemp =socketarray[nindex];
6if(dwtranslatebytes == 0) //
若接收到的位元組數為0,則說明客戶端已經關閉連線了,則我們也可以把相應的套接字關閉了712
else
13
9、到這裡我們從客戶端接收資料就完成了。但是還有幾個問題就是,為了能夠容納更多的客戶端連線我們應該建立額外的工作執行緒來處理和管理多客戶端連線。在這裡,我們只是說明一下重疊i/o模型的用法,就額外開闢兩個執行緒,乙個用來不斷的利用監聽套接字來對客戶端進行監聽,來進行和客戶端連線,另外乙個執行緒就是不斷獲取在重疊模型上發生的操作。
套接字之重疊I O模型
剛剛把重疊i o套接字理解了一點,於是在此做個筆記,給出乙個重疊i o處理單個套接字的程式。這個程式是tcp的伺服器端程式。該程式只能接收乙個客戶端的連線,迴圈傳送資訊,以及該客戶端退出時伺服器端得到響應。套接字型檔初始化等 省略了,只包含乙個監聽部分和乙個處理i o部分的 如下 開始進行重疊i o...
非同步通知I O模型和重疊I O模型
理解非同步通知i o模型 理解同步和非同步 同步i o的缺點及非同步方式的解決方案 理解非同步通知i o模型 實現非同步通知i o模型 wsaeventselect函式和通知 include intwsaeventselect socket s,wsaevent heventobject,long ...
WinSock重疊IO模型一
winsock的重疊io模型也就是重疊io的乙個特例罷了。其實就是把套接字當成檔案來操作。在重疊io中,如果讀大檔案的時候,為了不在那裡幹等。告訴系統,我先去下兩盤象棋,你讀完了,告訴我一下。下棋時視窗是全屏的,讀完後,彈乙個對話方塊出來告訴我下吧。恩,下棋,真是浪費時間的事,得戒掉啊。winsoc...