程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> .NET Socket開發之異步Socket

.NET Socket開發之異步Socket

編輯:關於.NET

在基於.NET的網絡服務端的開發中,我們用到和聽到的最多的恐怕就是異步 Socket了。異步Socket的性能比同步高出很多,但是編寫代碼比較復雜。因此異 步Socket也是網絡上討論比較多的話題。

今天,我們就來討論一下如何 用異步Socket開發網絡應用。在此之前我們先討論兩個問題。

一、異步 Socket是如何工作的:

那異步Socket是如何工作的呢?我以接收一條消 息來說明這個問題。首先,程序向系統投遞一個接收數據的請求,並為其指定一 個數據緩沖區和回調函數,回調函數用來指示當數據到達後將如何處理,然後我 們的程序繼續執行下去,當有數據到達的時候,系統將數據讀入緩沖區,並執行 回調函數,處理這條消息。我們並不需要關心這條消息何時到達。

二、 什麼情況下我們用異步Socket:

有些人認為,異步Socket的性能比同步 Socket的性能高很多,應該在各種環境下都用異步Socket,其實不然。在某些環 境下面。異步反到比同步的性能低,那麼在哪些情況下會這樣呢?

1、 客戶端Socket。

2、服務端連接數比較少。

3、連接數很多,但 都是短連接。

在這些環境下,我們用同步Socket不但可以簡化代碼,而 且性能並不會比異步Socket低。但在服務端連接比較多而且是長連接的情況下, 我們就要使用異步Socket。

現在我們來看看如何用異步Socket編程。

首先,我們要建立一個Socket用來監聽:

Socket _listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint localEP = new IPEndPoint(_address, _port);
_listener.Bind(localEP);
_listener.Listen (100);

然後創建一個線程來處理客戶端連接請求:

Thread _acceptWorkThread = new Thread (AcceptWorkThread);
_acceptWorkThread.Start();

private void AcceptWorkThread()
{
while (_isListener)
{
UserInfo info = new UserInfo();//這個UserInfo是用來保存客戶信息的。
info.socket = socket;
Socket socket = _listener.Accept ();
//這裡進行其它處理。
socket.BeginReceive(info.Buffer, 0, info.Buffer.Length, SocketFlags.None, ReceiveCallBack, info);//這裡向 系統投遞一個接收信息的請求,並為其指定ReceiveCallBack做為回調函數
}
}

我們再來看看回調函數的定義:

private void ReceiveCallBack(IAsyncResult ar)
{
UserInfo info = (UserInfo)ar.AsyncState;
Socket handler = info.socket;
int readCount = 0;
try
{
readCount = handler.EndReceive(ar);//調用這個函數來結束本次接收並返回接收到的數據 長度。
}
catch (SocketException)//出現Socket異常就關閉連接
{
CloseSocket(info);//這個函數用來關閉客戶端連接
return;
}
catch
{
}
if (readCount > 0)
{
byte[] buffer = new byte[readCount];
Buffer.BlockCopy(info.Buffer, 0, buffer, 0, readCount);
Analyzer(info, buffer);//這個函數用來處理接收到的信息。
try
{
handler.BeginReceive(info.Buffer, 0, info.Buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallBack), info);//向系統投 遞下一個接收請求
}
catch (SocketException) //出現Socket異常 就關閉連接
{
CloseSocket(info);
}
catch
{
}
}
else //如果接收到0字節的數據說明客戶端關閉了Socket,那 我們也要關閉Socket
{
CloseSocket(info);
}
}

接下來我們看看如何發送數據給客戶端:

public void Send(Socket socket, byte message)
{
try
{
info.socket.BeginSend(message, 0, _byte.Length, SocketFlags.None, new AsyncCallback(SendCallBack), info);//這裡向系統投遞一個發送數據的 請求,並指定一個回調函數。
}
catch (SocketException ex)
{
CloseSocket(info);
}
catch
{
}
}

定義發送回調函數:

private void SendCallBack(IAsyncResult ar)
{
UserInfo info = (UserInfo) ar.AsyncState;
try
{
info.socket.EndSend(ar);//調用這個 函數來結束本次發送。
}
catch
{
}
}

好了,整個監聽、接收、發送的過程就完成了,很簡單吧。現在 需要說明的是,我在這裡接收客戶端連接的Accept是用的同步的,我個人認為在 這裡用同步的會比用異步好一些。因為這樣代碼簡單而且沒有性能上的損失。

今天我就寫到這裡了!下次我們再繼續。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved