首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

.NET Socket 開發實戰:非同步 Socket 完整實作模式

     編輯:關於.NET

高併發伺服器開發首選非同步 Socket,效能遠優於同步阻塞模型。本文詳述監聽、接收、發送的非同步流程與關鍵程式碼模式。

適用場景判斷

場景建議模型
用戶端 Socket同步
伺服端連線數少同步
大量短連線同步
伺服端大量長連線非同步

核心流程

1. 建立監聽 Socket

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

2. 專用執行緒 Accept 連線 (同步 Accept 即可)

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

private void AcceptWorkThread()
{
    while (_isListening)
    {
        UserInfo info = new UserInfo(); // 自訂狀態物件
        Socket client = _listener.Accept();
        info.Socket = client;
        // 投遞第一個非同步接收
        client.BeginReceive(info.Buffer, 0, info.Buffer.Length, SocketFlags.None,
            ReceiveCallBack, info);
    }
}

3. 接收回呼:處理資料並投遞下一次接收

private void ReceiveCallBack(IAsyncResult ar)
{
    UserInfo info = (UserInfo)ar.AsyncState;
    Socket handler = info.Socket;
    int readCount = 0;
    try { readCount = handler.EndReceive(ar); }
    catch (SocketException) { CloseSocket(info); return; }

    if (readCount > 0)
    {
        byte[] data = new byte[readCount];
        Buffer.BlockCopy(info.Buffer, 0, data, 0, readCount);
        Analyzer(info, data); // 業務處理

        // 投遞下一次接收 (關鍵:形成接收循環)
        try
        {
            handler.BeginReceive(info.Buffer, 0, info.Buffer.Length, SocketFlags.None,
                ReceiveCallBack, info);
        }
        catch (SocketException) { CloseSocket(info); }
    }
    else // 收到 0 位元組 = 客戶端關閉
        CloseSocket(info);
}

4. 非同步發送

public void Send(Socket socket, byte[] message)
{
    try
    {
        socket.BeginSend(message, 0, message.Length, SocketFlags.None,
            SendCallBack, new UserInfo { Socket = socket });
    }
    catch (SocketException) { /* 處理錯誤 */ }
}

private void SendCallBack(IAsyncResult ar)
{
    UserInfo info = (UserInfo)ar.AsyncState;
    try { info.Socket.EndSend(ar); }
    catch { /* 忽略或記錄 */ }
}

關鍵設計要點

  • 狀態物件:UserInfo 封裝 Socket、緩衝區、使用者資料,透過 AsyncState 在回呼間流轉。
  • 接收循環:每次 EndReceive 後必須再次 BeginReceive,維持持續接收。
  • 同步 Accept:監聽迴圈使用同步 Accept 簡化邏輯,不影響效能(Accept 本身快速且非瓶頸)。
  • 例外處理:SocketException 通常代表連線斷開,統一在 CloseSocket 清理資源。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved