WinSock網路通訊程式設計入門

2021-04-01 02:41:15 字數 3183 閱讀 1138

對於許多初學者來說,網路通訊程式的開發,普遍的乙個現象就是覺得難以入手。許多概念,諸如:同步(sync)/非同步(async),阻塞(block)/非阻塞(unblock)等,初學者往往迷惑不清,只知其所以而不知起所以然。

同步方式指的是傳送方不等接收方響應,便接著發下個資料報的通訊方式;而非同步指傳送方發出資料後,等收到接收方發回的響應,才發下乙個資料報的通訊方式。

阻塞套接字是指執行此套接字的網路呼叫時,直到成功才返回,否則一直阻塞在此網路呼叫上,比如呼叫recv()函式讀取網路緩衝區中的資料,如果沒有資料到達,將一直掛在recv()這個函式呼叫上,直到讀到一些資料,此函式呼叫才返回;而非阻塞套接字是指執行此套接字的網路呼叫時,不管是否執行成功,都立即返回。比如呼叫recv()函式讀取網路緩衝區中資料,不管是否讀到資料都立即返回,而不會一直掛在此函式呼叫上。在實際windows網路通訊軟體開發中,非同步非阻塞套接字是用的最多的。平常所說的c/s(客戶端/伺服器)結構的軟體就是非同步非阻塞模式的。

對於這些概念,初學者的理解也許只能似是而非,我將用乙個最簡單的例子說明非同步非阻塞socket的基本原理和工作機制。目的是讓初學者不僅對socket非同步非阻塞的概念有個非常透徹的理解,而且也給他們提供乙個用socket開發網路通訊應用程式的快速入門方法。作業系統是windows 98(或nt4.0),開發工具是visual c++6.0。

mfc提供了乙個非同步類casyncsocket,它封裝了非同步、非阻塞socket的基本功能,用它做常用的網路通訊軟體很方便。但它遮蔽了socket的非同步、非阻塞等概念,開發人員無需了解非同步、非阻塞socket 的原理和工作機制。因此,建議初學者學習編網路通訊程式時,暫且不要用mfc提供的類,而先用winsock2 api,這樣有助於對非同步、非阻塞socket程式設計機制的理解。

為了簡單起見,伺服器端和客戶端的應用程式均是基於mfc的標準對話方塊,網路通訊部分基於winsock2 api實現。

先做伺服器端應用程式

用mfc嚮導做乙個基於對話方塊的應用程式socketsever,注意第三步中不要選上windwos sockets選項。在做好工程後,建立乙個seversock,將它設定為非同步非阻塞模式,並為它註冊各種網路非同步事件,然後與自定義的網路非同步事件聯絡上,最後還要將它設定為監聽模式。在自定義的網路非同步事件的**函式中,你可以得到各種網路非同步事件,根據它們的型別,做不同的處理。下面將詳細介紹如何編寫相關**。

在socketseverdlg.h檔案的類定義之前增加如下定義:

#define ***work_event wm_user+166 file://定義網路事件

socket serversock; file://伺服器端socket

在類定義中增加如下定義:

class csocketseverdlg : cdialog

;在socketseverdlg.cpp檔案中增加訊息對映,其中on***event是非同步事件**函式名:

on_message(***work_event,on***event)

定義初始化網路函式,在socketseverdlg.cpp檔案的oninitdialog()中調此函式即可。

bool csocketseverdlg::init***work()

file://建立伺服器端套接字

serversock = socket(af_i***, sock_stream, ipproto_tcp);

if(serversock == invalid_socket)

file://繫結到本地乙個埠上

sockaddr_in localaddr;

localaddr.sin_family = af_i***;

localaddr.sin_port = htons(8888); file://埠號不要與其他應用程式衝突

localaddr.sin_addr.s_addr = 0;

if(bind(serversock ,(struct sockaddr*)&localaddr,sizeof(sockaddr))

= = socket_error)

file://將seversock設定為非同步非阻塞模式,並為它註冊各種網路非同步事件,其 中 m_hwnd

file://為應用程式的主對話方塊或主視窗的控制代碼

if(wsaasyncselect(serversock, m_hwnd, ***work_event,

fd_accept | fd_close | fd_read | fd_write) == socket_error)

listen(serversock, 5); file://設定偵聽模式

return true;

}下面定義網路非同步事件的**函式

void csocketseverdlg::on***event(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網路通訊 這裡我希望和大家 一下winsock網上通訊的程式,由於網際網路的普及,越來越多的程式具有了在網上與其他程式通訊的功能.其實所有這些功能都建立在winsock介面之上,應用程式執行大多數網路通訊的基本物件稱為套介面或軟插口 socket 使用mfc winsocket類新增網...

Winsock網路通訊

winsock網路通訊 這裡我希望和大家 一下winsock網上通訊的程式,由於網際網路的普及,越來越多的程式具有了在網上與其他程式通訊的功能.其實所有這些功能都建立在winsock介面之上,應用程式執行大多數網路通訊的基本物件稱為套介面或軟插口 socket 使用mfc winsocket類新增網...

Winsock開發網路通訊程式的經典入門

對於許多初學者來說,網路通訊程式的開發,普遍的乙個現象就是覺得難以入手。許多概念,諸如 同步 sync 非同步 async 阻塞 block 非阻塞 unblock 等,初學者往往迷惑不清,只知其所以而不知起所以然。同步方式指的是傳送方不等接收方響應,便接著發下個資料報的通訊方式 而非同步指傳送方發...