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

C# Socket 同步通信完整實現:客戶端與服務端代碼詳解

     編輯:關於C#

一、同步 Socket 特點

  • 阻塞模式:Connect、Send、Receive、Accept 均阻塞當前線程,直到操作完成。
  • 代碼線性直觀:無回調/異步狀態機,邏輯易讀寫。
  • 適用場景:低併發、內部工具、測試驗證、教學演示。高併發生產環境請用異步或 async/await。

二、同步客戶端完整代碼

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;

public class SyncTcpClient {
    public static void Start(string serverIp = "127.0.0.1", int port = 11000) {
        byte[] buffer = new byte[1024];
        try {
            // 解析服務端地址
            IPHostEntry host = Dns.GetHostEntry(serverIp);
            IPAddress ip = host.AddressList.FirstOrDefault(a => a.AddressFamily == AddressFamily.InterNetwork) 
                           ?? host.AddressList[0];
            IPEndPoint remoteEP = new IPEndPoint(ip, port);
            
            // 創建 TCP Socket
            using (Socket sender = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) {
                Console.WriteLine($"Connecting to {remoteEP}...");
                sender.Connect(remoteEP); // 阻塞直到連接成功或異常
                Console.WriteLine($"Connected to {sender.RemoteEndPoint}");
                
                // 發送數據(帶結束標記)
                string message = "This is a test";
                byte[] msgBytes = Encoding.ASCII.GetBytes(message);
                int bytesSent = sender.Send(msgBytes); // 阻塞直到發送完成
                Console.WriteLine($"Sent {bytesSent} bytes.");
                
                // 接收響應
                int bytesRec = sender.Receive(buffer); // 阻塞直到收到數據
                string response = Encoding.ASCII.GetString(buffer, 0, bytesRec);
                Console.WriteLine($"Received: {response}");
                
                // 正確關閉
                sender.Shutdown(SocketShutdown.Both);
            }
        } catch (SocketException ex) {
            Console.WriteLine($"Socket Error: {ex.SocketErrorCode} - {ex.Message}");
        } catch (Exception ex) {
            Console.WriteLine($"Error: {ex.Message}");
        }
    }
    
    public static void Main() => Start();
}

三、同步服務端完整代碼

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;

public class SyncTcpServer {
    public static void Start(int port = 11000) {
        byte[] buffer = new byte[1024];
        try {
            IPHostEntry host = Dns.GetHostEntry("127.0.0.1");
            IPAddress ip = host.AddressList.FirstOrDefault(a => a.AddressFamily == AddressFamily.InterNetwork)
                           ?? host.AddressList[0];
            IPEndPoint localEP = new IPEndPoint(ip, port);
            
            using (Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) {
                listener.Bind(localEP);
                listener.Listen(10); // 等待隊列長度
                Console.WriteLine($"Server listening on {localEP}...");
                
                while (true) { // 持續接受連接
                    Console.WriteLine("Waiting for connection...");
                    Socket handler = listener.Accept(); // 阻塞直到客戶端連接
                    Console.WriteLine($"Client connected: {handler.RemoteEndPoint}");
                    
                    StringBuilder receivedData = new StringBuilder();
                    try {
                        while (true) {
                            int bytesRec = handler.Receive(buffer); // 阻塞接收
                            if (bytesRec == 0) break; // 客戶端主動斷開
                            receivedData.Append(Encoding.ASCII.GetString(buffer, 0, bytesRec));
                            if (receivedData.ToString().Contains("")) break; // 協議結束標記
                        }
                        Console.WriteLine($"Received: {receivedData}");
                        
                        // 回聲響應
                        byte[] response = Encoding.ASCII.GetBytes(receivedData.ToString());
                        handler.Send(response);
                    } finally {
                        handler.Shutdown(SocketShutdown.Both);
                        handler.Close();
                    }
                }
            }
        } catch (Exception ex) {
            Console.WriteLine($"Server Error: {ex.Message}");
        }
    }
    
    public static void Main() => Start();
}

四、關鍵協議設計點

  1. 消息邊界:TCP 是流協議,無消息邊界。示例用 <EOF> 標記結束,實際項目建議:定長頭部+長度字段、或特定分隔符、或序列化框架。
  2. 編碼一致性:雙端統一編碼(示例用 ASCII,實際常用 UTF-8)。
  3. 緩衝區大小:1024 字節為示例值,實際按 MTU/業務包大小調整。
  4. 優雅關閉:Shutdown(Both) 發送 FIN 包,再 Close() 釋放資源。

五、常見異常處理

異常原因處理
SocketException: ConnectionRefused服務端未啟動/端口錯誤/防火牆檢查服務端、端口、防火牆規則
SocketException: TimedOut網絡不可達/服務端無響應設置 SendTimeout/ReceiveTimeout、檢查網絡
ObjectDisposedExceptionSocket 已關閉後繼續操作檢查生命週期管理、使用 using
ArgumentNullException傳入 null 緩衝區/地址參數驗證

六、進階:簡易控制台聊天雙向通信

需雙線程:主線程 Receive 循環,子線程讀取控制台輸入 Send。或用 Select/Poll 多路復用單線程處理。異步模式下 BeginSend/EndSend、BeginReceive/EndReceive 或 await SendAsync/ReceiveAsync 更優雅。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved