當前位置:編程學習大全網 - 編程語言 - 如何使用SocketAsyncEventArgs類

如何使用SocketAsyncEventArgs類

由於減少了阻塞線程,高性能I/O限制應用中廣泛使用異步編程模型(AMP,Asynchronous Programming Model)。.NET Framework第壹個版本就實現了APM,現在使用諸如lambda表達式等新的技術C#3.0壹直在改進其性能。針對Socket編程,不僅性能上 提升了不少,而且新APM模型發布了壹個更簡易的編程方法,該方法使用SocketAsyncEventArgs類來保持I/O操作之間的上下文,從而降低對象分配和垃圾收集工作。

在.NET 2.0 SP1上可以使用SocketAsyncEventArgs類,本文的代碼就是用Microsoft Visual Studio .NET 2005編寫的。

使用代碼

從SocketAsyncEventArgs類開始,我學習了MSDN上 的樣例程序,但該文缺少壹些內容:AsyncUserToken類。我認為這個類應該公開壹個Socket屬性,它對應執行I/O操作的Socket。壹 段時間後,我認識到這個類不是必要的,因為屬性UserToken是壹個Object,它可以接受任何東西。下面的修改方法中直接使用壹個Socket實 例當作UserToken。

我修改了如何操作偵聽者收到消息的代碼——不是簡單地回發給客戶端(參見ProcessReceive方法)。在樣例程序中,我使用屬性Buffer、Offset與BytesTransfered來接收消息,SetBuffer方法把修改後的消息回返給客戶端。 為了控制偵聽者生存期時間,使用了壹個Mutex類的實例。基於原Init方法的Start方法創建Mutex對象,相應的Stop方法釋放Mutex對象。這些方法適用於實現作為Windows服務的Socket服務器。

現在,我們有了壹個Socket服務器,下壹步使用SocketAsyncEventArgs類建立壹個Socket客戶端。雖然MSDN說這個類特別設計給網絡服務器應用,但也沒有限制在客戶端代碼中使用APM。下面給出了SocketClient類的樣例代碼:

  // ?失敗時關閉Socket,根據SocketError拋出異常。

private void ProcessError(SocketAsyncEventArgs e)

{

Socket s = e.UserToken as Socket;

if (s.Connected)

{

// ?關閉與客戶端關聯的Socket

try

{

s.Shutdown(SocketShutdown.Both);

}

catch (Exception)

{

// ?如果客戶端處理已經關閉,拋出異常

}

finally

{

if (s.Connected)

{

s.Close();

}

}

}

// ?拋出SocketException

throw new SocketException((Int32)e.SocketError);

}

// ?與主機交換消息。

internal String SendReceive(String message)

{

if (connected)

{

// ?創建壹個發送緩沖區。

Byte [] sendBuffer = Encoding.ASCII.GetBytes(message);

// ?準備發送/接收操作的參數。

SocketAsyncEventArgs completeArgs = new SocketAsyncEventArgs();

completeArgs.SetBuffer(sendBuffer, 0, sendBuffer.Length);

completeArgs.UserToken = clientSocket;

completeArgs.RemoteEndPoint = hostEndPoint;

completeArgs.Completed +=

? new EventHandler<socketasynceventargs>(OnSend);

// ?開始異步發送。

clientSocket.SendAsync(completeArgs);

// ?等待發送/接收完成。

AutoResetEvent.WaitAll(autoSendReceiveEvents);

// ?從SocketAsyncEventArgs緩沖區返回數據。

return Encoding.ASCII.GetString(completeArgs.Buffer,

completeArgs.Offset, completeArgs.BytesTransferred);

}

else

{

throw new SocketException((Int32)SocketError.NotConnected);

}

}

#region IDisposable Members

// 釋放SocketClient實例。

public void Dispose()

{

autoConnectEvent.Close();

autoSendReceiveEvents[SendOperation].Close();

autoSendReceiveEvents[ReceiveOperation].Close();

if (clientSocket.Connected)

{

clientSocket.Close();

}

}

#endregion

}

} 轉載僅供參考,版權屬於原作者。祝妳愉快,滿意請采納哦

  • 上一篇:對於壹個程序員用Mac OS X 和windows哪個更好壹些
  • 下一篇:誰能告訴我學C++的最好方法?我剛學了幾天,有點煩躁,很多專有名詞啊!
  • copyright 2024編程學習大全網