續例項解析SOCKET程式設計模型之非同步通訊篇(下)

2021-04-13 03:26:31 字數 3271 閱讀 3488

非同步客戶端套接字在等待網路操作完成時不掛起應用程式。相反,它使用標準 .net framework

非同步程式設計模型在乙個執行緒上處理網路連線,而應用程式繼續在原始執行緒上執行。非同步套接字適用於大量使用網路或不能等待網路操作完成才能繼續的應用程式。

socket

類遵循非同步方法的 .net framework 命名模式;例如,同步

receive

方法對應非同步

beginreceive

和 endreceive

方法。非同步操作要求**方法返回操作結果。如果應用程式不需要知道結果,則不需要任何**方法。本節中的**示例闡釋如何使用某個方法開始與網路裝置的連線並使用**方法結束連線,如何使用某個方法開始傳送資料並使用**方法完成傳送,以及如何使用某個方法開始接收資料並使用**方法結束接收資料。

非同步套接字使用多個系統執行緒池中的執行緒處理網路連線。乙個執行緒負責初始化資料的傳送或接收;其他執行緒完成與網路裝置的連線並傳送或接收資料。在程式原始碼中,

system.threading.manualresetevent

類的例項用於掛起主線程的執行並在執行可以繼續時發出訊號。

在客戶端原始碼中,為了將非同步套接字連線到網路裝置,socket方法初始化乙個socket,然後呼叫

beginconnect

方法,傳遞表示網路裝置的遠端終結點、連線**方法以及狀態物件(即客戶端socket,用於在非同步呼叫之間傳遞狀態資訊)。該示例實現connect方法以將指定的socket連線到指定的終結點。它採用乙個名為connectdone的全域性manualresetevent:   publiciasyncresultbeginconnect(

endpointremoteep,

asynccallbackcallback,

objectstate

);

連線**方法connectcallback實現

asynccallback

委託。它在遠端裝置可用時連線到遠端裝置,然後通過設定manualreseteventconnectdone向應用程式執行緒發出連線完成的訊號。下面的客戶端原始碼中實現了connectcallback方法。

send 示例方法以 ascii 格式對指定的字串資料進行編碼,並將其非同步傳送到指定的套接字所表示的網路裝置。

傳送**方法sendcallback實現

asynccallback

委託。它在網路裝置準備接收時傳送資料。下面的原始碼中實現了sendcallback方法。它採用乙個名為senddone的全域性manualresetevent

從客戶端套接字讀取資料需要乙個在非同步呼叫之間傳遞值的狀態物件。下面的類是用於從客戶端套接字接收資料的示例狀態物件。它包含以下各項的字段:客戶端套接字,用於接收資料的緩衝區,以及用於儲存傳入資料字串的

stringbuilder

。將這些字段放在該狀態物件中,使這些欄位的值在多個呼叫之間得以保留,以便從客戶端套接字讀取資料。

public class stateobject   //為簡單起見,客戶端原始碼中並未建立此類

receive 方法示例設定狀態物件,然後呼叫beginreceive方法從客戶端套接字非同步讀取資料。

接收**方法receivecallback實現asynccallback委託。它接收來自網路裝置的資料並生成訊息字串。它將來自網路的乙個或多個資料位元組讀入資料緩衝區,然後再次呼叫beginreceive方法,直到客戶端傳送的資料完成為止。從客戶端讀取所有資料後,receivecallback通過設定manualreseteventsenddone向應用程式執行緒發出資料完成的訊號。         

//以下是客戶端詳細實現**

using system;

using system.drawing;

using system.collections;

using system.componentmodel;

using system.windows.forms;

using system.data;

using system.net;

using system.net.sockets;

using system.threading;

using system.text;

namespace 聊天_socket_client

///

/// 清理所有正在使用的資源。

///

protected override void dispose( bool disposing )

}base.dispose( disposing );}

#region windows 窗體設計器生成的**

///

/// 設計器支援所需的方法 - 不要使用**編輯器修改

/// 此方法的內容。

///

private void initializecomponent()

#endregion

///

/// 應用程式的主入口點。

///

private void btnsend_click(object sender, system.eventargs e)

catch}

private void btnstop_click(object sender, system.eventargs e)

catch}

private void form1_closing(object sender, system.componentmodel.canceleventargs e)

catch{}}}

}

例項解析SOCKET程式設計模型(二)

以下是同步聊天程式的客戶端源 其中的一些過程可以參考伺服器端原始碼 using system using system.drawing using system.collections using system.componentmodel using system.windows.forms us...

Socket程式設計小結(續)

1.重用已使用的位址 問題描述 在剛剛關閉了測試程式後,再啟動伺服器時提示bind失敗,返回錯誤eaddrinuse。原因分析 套接字 主動關閉一端 在關閉套接字後會停留在time wait狀態一端時間,由於我在同一機器上同時執行客戶端與伺服器,故伺服器在重新啟動執行bind時,可能上次關閉連線還沒...

Socket程式設計例項

struct sockaddr sockaddr定義的標頭檔案 sys socket.h struct sockaddr in sockaddr in解決了sockaddr 的缺陷,實際上相當於把sockaddr 中的sa data分成了3個部分 sockaddr in 定義的標頭檔案 netine...