用Socket介面實現網路非同步通訊

2021-04-16 11:56:10 字數 3903 閱讀 6042

馬愛民

vc ++ 4.1以上版本的開發環境提供了socket介面,可以方便地進行網路通訊。本文是在乙個應用程式中利用socket介面實現非同步通訊,由於在非同步通訊狀態下,服務端和客戶端主控程式在等待資訊時可以完成其他工作,因此具有更廣闊的應用領域。

1.建立應用程式框架

mainfraim.h mainfraim.cpp

childview.h childview.cpp

下面在上述程式框架的基礎上編寫乙個能進行非同步通訊的應用程式。

2.流式套接字通訊原理

流式套接字因其可靠性高而得到廣泛的應用。其通訊原理為:服務端和客戶端都必須建立通訊套接字,而且服務端應先進入監聽狀態,然後客戶端套接字發出連線請求,服務端收到請求後,建立另乙個套接字進行通訊,原來負責監聽的套接字仍進行監聽,如果有其他客戶發來連線請求,則再建立乙個套接字。預設狀態下最多可同時接收5個客戶的連線請求,並建立通訊關係。

3.定義mysocket類

本例中為了實現套接字的網路非同步通訊,通過非同步套接字類casycnsocket派生出兩個新類。**的生成可以利用classwizard來建立程式框架,給兩個派生類取名為mysocket和servesocket,生成時使用的基類為casycnsocket,並可將它們放在同一組檔案中(本例是放在mysocket.h和mysocket.cpp中)。接著在classwizard中為mysocket類加入onaccept()和onreceive()兩個函式;為servesocket類加入onreceive()函式。注意,這些函式都是過載函式,不能隨便給其命名,加入函式的方法是:在classwizard的object ids視窗中選中最後一行,然後在message視窗中選擇相應的函式即可。

兩個派生類的功能是:mysocket類用於在服務端和客戶端建立套接字,分別用於監聽和通訊;servesocket類用於在服務端建立通訊套接字,它是在服務端監聽到連線請求後才建立的,因此本例中將它作為mysocket類的成員變數。為了使服務端能響應多個客戶的請求,可以建立5個servesocket型別的套接字,並設立乙個記錄器,記錄已經收到的請求個數,該記錄器在mysocket的建構函式中被置為0。

完成非同步通訊的關鍵在於上述三個過載函式,它們從網路中傳來資訊時,可以被自動呼叫,以完成接收工作。在本例中,onaccept()函式在收到連線請求後,會向客戶發出乙個代表其序號的資訊;兩個onreceive()函式都進行提示,並在確認後將收到的資訊傳送回去。上述兩個派生類的源**在網上,**為www.pccomputing.com.cn。

4.完成服務端或客戶端的設定

通過選單項完成的設定工作可以有多種安排方法,本例為了便於顯示,將設定工作安排在cchildview類中。首先用資源編輯器在主選單中增加server和client兩個選項,並定義它們的id,然後用classwizard在cchildview類中增加對這兩個id的響應函式,並在其中分別建立套接字後進入監聽或開始連線。為了便於觀察工作程序,可在其中增加相應的輸出語句,另外,在childview.h和childview.cpp檔案前面必須有#include "mysocket.h"語句。

為了簡化程式,本程式直接寫入服務主機的ip位址,因此,本程式在使用時,服務端是指定的,不能隨便改變,但客戶端的位置不受限制。

5.程式的使用

本程式可以在同一網路中的不同主機之間進行非同步通訊。以兩台主機為例,首先在指定的主機上啟動本程式,並在選單中選擇server選項,使程式進入監聽狀態;然後在另一主機上啟動本程式並選擇client選項,向服務端發出連線請求;服務端收到連線請求後,自動呼叫onaccept()函式,根據客戶端的請求順序向其發出相應資訊;客戶端接收到服務端發出的資訊後,在螢幕上顯示乙個提示框,按下「確認」按鈕後,客戶端將此資訊發回服務端;服務端收到客戶端發回的資訊後,處理方式與客戶端相同,就是這樣實現了這個資訊在兩台計算機之間的來回傳遞。值得注意的是,在等待資訊期間,這個程式還可以做其他的工作,比如可以選擇選單上的某個選項等,當然也可以加入其他的工作。

執行本程式並選擇作為服務端時最多可以同時接收五個客戶的請求,因此可以同時執行本程式的六個例項,其中乙個設定為服務端,另外五個設定為客戶端。由於服務端實際上是用五個套接字分別與客戶端通訊,因此點對點的通訊過程將會互不干擾地進行。

6.源程式

本文給出框架中被改動過的檔案**(即mysocket和childview的.h和.cpp檔案的源**)如下,這些程式均在vc ++ 6.0下編譯通過,並在本文作者單位的網路環境上執行成功。

mysocket.h檔案:

//派生套接字類

class servesocket : public casyncsocket

}afx_virtual

class mysocket : public casyncsocket

public:

servesocket servesocket[5];

int acceptno;

int connectno;

char rx_buf[100];

public:

mysocket();

virtual ~mysocket();

public:

// classwizard generated virtual function overrides

//}afx_virtual

mysocket.cpp檔案中的有關部分:

void servesocket::onreceive(int nerrorcode)

if(receive(rx_buf,100))

case 1:

case 2:

case 3:

case 4:

default:

break;

// afxmessagebox("accept client!",14);

acceptno++;

casyncsocket::onaccept(nerrorcode);

void mysocket::onreceive(int nerrorcode)

if(receive(rx_buf,100))

afx_msg void onpaint();

afx_msg void onclient();

afx_msg void onserver();

//}}afx_msg declare_message_map()

4.childview.cpp檔案中的有關部分

begin_message_map(cchildview,cwnd )

//}afx_msg_map

end_message_map()

void cchildview::onclient()

cclientdc dc(this);

//creat a socket

socket_id.create();

dc.textout(200,100,"connect",7);

if(socket_id.connect("192.0.0.0",2000))

//服務端主機ip位址和埠號

dc.textout(200,120,"connect fail!",13);

else

dc.textout(200,120,"connect successful!",18);

void cchildview::onserver()

cclientdc dc(this);

//建立已定義的套接字

socket_id.create(2000);

//為其分配乙個埠(2000)

//socket_id.bind(2000,"192.0.0.0");

//埠號和服務端主機ip位址。不同的主機此位址不同。

//開始監聽

dc.textout(200,100,"listen",6);

socket_id.listen();

用Socket介面實現網路非同步通訊

馬愛民 vc 4.1以上版本的開發環境提供了socket介面,可以方便地進行網路通訊。本文是在乙個應用程式中利用socket介面實現非同步通訊,由於在非同步通訊狀態下,服務端和客戶端主控程式在等待資訊時可以完成其他工作,因此具有更廣闊的應用領域。1 建立應用程式框架 mainfraim.h main...

用Socket介面實現網路非同步通訊

馬愛民 vc 4.1以上版本的開發環境提供了socket介面,可以方便地進行網路通訊。本文是在乙個應用程式中利用socket介面實現非同步通訊,由於在非同步通訊狀態下,服務端和客戶端主控程式在等待資訊時可以完成其他工作,因此具有更廣闊的應用領域。1 建立應用程式框架 mainfraim.h main...

Java 用socket實現網路通訊

這裡用乙個程序的兩個執行緒之間實現socket通訊。執行的結果是不停列印出server 但是如果服務端在mac,而客戶端在android,是沒有辦法通訊的,暫時還不知道為什麼。public static void main string args throws ioexception catch i...