網路通訊程式的開發,有許多概念,諸如:同步(sync)/非同步(async),阻塞(block)/非阻塞(unblock)等。
同步方式指的是傳送方不等接收方響應,便接著發下個資料報的通訊方式;而非同步指傳送方發出資料後,等收到接收方發回的響應,才發下乙個資料報的通訊方式。
阻塞套接字是指執行此套接字的網路呼叫時,直到成功才返回,否則一直阻塞在此網路呼叫上,比如呼叫recv()函式讀取網路緩衝區中的資料,如果沒有資料到達,將一直掛在recv()這個函式呼叫上,直到讀到一些資料,此函式呼叫才返回;而非阻塞套接字是指執行此套接字的網路呼叫時,不管是否執行成功,都立即返回。比如呼叫recv()函式讀取網路緩衝區中資料,不管是否讀到資料都立即返回,而不會一直掛在此函式呼叫上。在實際windows網路通訊軟體開發中,非同步非阻塞套接字是用的最多的。平常所說的c/s(客戶端/伺服器)結構的軟體就是非同步非阻塞模式的。
mfc提供了乙個非同步類casyncsocket,它封裝了非同步、非阻塞socket的基本功能,用它做常用的網路通訊軟體很方便。但它遮蔽了socket的非同步、非阻塞等概念,開發人員無需了解非同步、非阻塞socket的原理和工作機制。因此,建議初學者學習編網路通訊程式時,暫且不要用mfc提供的類,而先用winsock2 api,這樣有助於對非同步、非阻塞socket程式設計機制的理解。
用乙個最簡單的例子說明非同步非阻塞socket的基本原理和工作機制。為了簡單起見,伺服器端和客戶端的應用程式均是基於mfc的標準對話方塊,網路通訊部分基於winsock2 api實現。
先做伺服器端應用程式。
用mfc嚮導做乙個基於對話方塊的應用程式socketsever,注意第三步中不要選上windwos sockets選項。在做好工程後,建立乙個seversock,將它設定為非同步非阻塞模式,並為它註冊各種網路非同步事件,然後與自定義的網路非同步事件聯絡上,最後還要將它設定為監聽模式。在自定義的網路非同步事件的**函式中,可以得到各種網路非同步事件,根據它們的型別,做不同的處理。下面詳細介紹如何編寫相關**。
在socketseverdlg.h檔案的類定義之前增加如下定義:
#define network_event wm_user+166file://
定義網路事件
socket serversock; file://
伺服器端socket
在類定義中增加如下定義:
class csocketseverdlg : cdialog
;
在socketseverdlg.cpp檔案中增加訊息對映,其中onnetevent是非同步事件**函式名:
on_message(network_event,onnetevent)
定義初始化網路函式,在socketseverdlg.cpp檔案的oninitdialog()中調此函式即可。
bool csocketseverdlg::initnetwork()
//建立伺服器端套接字
serversock = socket(af_inet, sock_stream, ipproto_tcp);
if(serversock == invalid_socket)
//繫結到本地乙個埠上
sockaddr_in localaddr;
localaddr.sin_family = af_inet;
localaddr.sin_port = htons(8888); //埠號不要與其他應用程式衝突
localaddr.sin_addr.s_addr = 0;
if(bind(serversock ,(struct sockaddr*)&localaddr,sizeof(sockaddr))= = socket_error)
//將seversock設定為非同步非阻塞模式,並為它註冊各種網路非同步事件,其中m_hwnd
//為應用程式的主對話方塊或主視窗的控制代碼
if(wsaasyncselect(serversock, m_hwnd, network_event, fd_accept | fd_close | fd_read | fd_write) == socket_error)
listen(serversock, 5); file://設定偵聽模式
return true;
}
下面定義網路非同步事件的**函式
void csocketseverdlg::onnetevent(wparam wparam, lparam lparam)
}
以下是發生在相應socket上的各種網路非同步事件的處理函式,其中onaccept傳進來的引數是伺服器端建立的套接字,onclose()、onreceive()和onsend()傳進來的引數均是伺服器端在接受客戶端連線時新建立的用與此客戶端通訊的socket。
void csocketseverdlg::onaccept(socket cursock)
void csocketseverdlg::onclose(socet cursock)
void csocketseverdlg::onsend(socet cursock)
void csocketseverdlg::onreceive(socet cursock)
用同樣的方法建立乙個客戶端應用程式。初始化網路部分,不需要將套接字設定為監聽模式。註冊非同步事件時,沒有fd_accept,但增加了fd_connect事件,因此沒有onaccept()函式,但增加了onconnect()函式。向伺服器發出連線請求時,使用connect()函式,連線成功後,會響應到onconnect()函式中。下面是onconnect()函式的定義,傳進來的引數是客戶端socket和伺服器端發回來的連線是否成功的標誌。
void csocketclntdlg::onconnect(socket cursock, int error)
}
·定義onreceive()函式,處理網路資料到達事件;
·定義onsend()函式,處理傳送網路資料事件;
·定義onclose()函式,處理伺服器的關閉事件。
以上就是用基於windows訊息機制的非同步i/o模型做伺服器和客戶端應用程式的基本方法。另外還可以用事件模型、重疊模型或完成埠模型。
在實現了上面的例子後,你將對winsock編網路通訊程式的機制有了一定的了解。
winSock網路程式設計初體驗
在windows下進行tcp的socket程式設計主要有以下步驟 1.初始化wsa winsock word wversionrequested wsadata wsadata wversionrequested makeword 2,0 if wsastartup wversionrequeste...
WinSock網路程式設計基礎(1)
記錄學習windows網路程式設計過程中遇到的問題和相關筆記 socket起源於unix,socket是應用層與tcp ip協議族通訊的中間軟體抽象層,它是一組介面。基於 開啟 讀 寫 關閉 模式,其中winsock就是變種之一 以下是乙個典型的c s中使用套接字介面的概述 winsock是wind...
WinSock網路通訊程式設計入門
對於許多初學者來說,網路通訊程式的開發,普遍的乙個現象就是覺得難以入手。許多概念,諸如 同步 sync 非同步 async 阻塞 block 非阻塞 unblock 等,初學者往往迷惑不清,只知其所以而不知起所以然。同步方式指的是傳送方不等接收方響應,便接著發下個資料報的通訊方式 而非同步指傳送方發...