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

C# Socket 程式設計完整教學:從基礎 Socket 到 TCP 通訊實作

     編輯:關於C語言

前言

Socket 是網路通訊的基礎建構元件。.NET 提供 System.Net.Sockets 命名空間,支援同步/非同步、TCP/UDP 多種模式。本文由淺入深,示範基礎 Socket、TCP Listener/Client 兩種常見架構,並附上完整的伺服器/用戶端範例。

一、基礎 Socket 架構 (同步阻塞)

伺服器端

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

public class SyncTcpServer
{
    private Socket _serverSocket;
    private Thread _listenThread;
    private readonly int _port = 8000;

    public void Start()
    {
        IPAddress ip = Dns.GetHostEntry(Dns.GetHostName()).AddressList[0];
        IPEndPoint localEndPoint = new IPEndPoint(ip, _port);

        _serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        _serverSocket.Bind(localEndPoint);
        _serverSocket.Listen(5);

        _listenThread = new Thread(ListenLoop) { IsBackground = true };
        _listenThread.Start();
        Console.WriteLine($"Server started on {localEndPoint}");
    }

    private void ListenLoop()
    {
        byte[] buffer = new byte[1024];
        while (true)
        {
            try
            {
                Socket clientSocket = _serverSocket.Accept(); // 阻塞等待連線
                int received = clientSocket.Receive(buffer);
                string msg = Encoding.Default.GetString(buffer, 0, received);
                string log = $"{DateTime.Now:HH:mm:ss} From {clientSocket.RemoteEndPoint}: {msg}";
                Console.WriteLine(log);
                
                // 簡單回應
                byte[] reply = Encoding.Default.GetBytes("Server received: " + msg);
                clientSocket.Send(reply);
                
                clientSocket.Shutdown(SocketShutdown.Both);
                clientSocket.Close();
            }
            catch (SocketException ex)
            {
                Console.WriteLine($"Socket error: {ex.Message}");
            }
            catch (ThreadAbortException) { break; }
        }
    }

    public void Stop()
    {
        _serverSocket?.Close();
        _listenThread?.Abort();
    }
}

用戶端

public class SyncTcpClient
{
    public void SendMessage(string serverIp, int port, string message)
    {
        using (Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp))
        {
            socket.Connect(serverIp, port);
            byte[] data = Encoding.ASCII.GetBytes(message);
            socket.Send(data);
            
            byte[] buffer = new byte[1024];
            int received = socket.Receive(buffer);
            Console.WriteLine($"Server reply: {Encoding.ASCII.GetString(buffer, 0, received)}");
        }
    }
}

二、高階 TCP 架構:TcpListener / TcpClient 搭配 NetworkStream

此模式封裝 Socket 細節,提供串流介面,適合文字訊息收發,支援 StreamReader/Writer 逐行讀寫。

伺服器端 (多執行緒處理多用戶)

using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading;

public class TcpStreamServer
{
    private TcpListener _listener;
    private Thread _listenThread;
    private bool _running = true;
    private readonly int _port = 8000;

    public void Start()
    {
        _listener = new TcpListener(IPAddress.Any, _port);
        _listener.Start();
        _listenThread = new Thread(AcceptClients) { IsBackground = true };
        _listenThread.Start();
        Console.WriteLine($"Stream server listening on port {_port}");
    }

    private void AcceptClients()
    {
        while (_running)
        {
            try
            {
                TcpClient client = _listener.AcceptTcpClient();
                ThreadPool.QueueUserWorkItem(HandleClient, client);
            }
            catch (SocketException) { if (_running) throw; }
        }
    }

    private void HandleClient(object state)
    {
        TcpClient client = (TcpClient)state;
        using (NetworkStream stream = client.GetStream())
        using (StreamReader reader = new StreamReader(stream))
        using (StreamWriter writer = new StreamWriter(stream) { AutoFlush = true })
        {
            Console.WriteLine($"Client connected: {client.Client.RemoteEndPoint}");
            string line;
            while (_running && (line = reader.ReadLine()) != null)
            {
                if (line == "STOP") break;
                Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] {line}");
                writer.WriteLine($"Echo: {line}");
            }
        }
        client.Close();
        Console.WriteLine("Client disconnected");
    }

    public void Stop()
    {
        _running = false;
        _listener?.Stop();
        _listenThread?.Join(1000);
    }
}

用戶端

public class TcpStreamClient
{
    private TcpClient _client;
    private StreamReader _reader;
    private StreamWriter _writer;

    public void Connect(string host, int port)
    {
        _client = new TcpClient(host, port);
        NetworkStream stream = _client.GetStream();
        _reader = new StreamReader(stream);
        _writer = new StreamWriter(stream) { AutoFlush = true };
        Console.WriteLine("Connected to server");
    }

    public void Send(string message)
    {
        if (string.IsNullOrEmpty(message)) return;
        _writer.WriteLine(message);
        string reply = _reader.ReadLine();
        Console.WriteLine($"Server: {reply}");
    }

    public void Disconnect()
    {
        _writer?.WriteLine("STOP");
        _writer?.Flush();
        _reader?.Close();
        _writer?.Close();
        _client?.Close();
    }
}

三、關鍵差異比較

特性基礎 SocketTcpListener/Client + Stream
控制層級完整控制封包、協定細節封裝良好,專注資料流
資料處理位元組陣列,需自行處理邊界串流,支援逐行/逐字元讀寫
非同步支援BeginAccept/Receive/Send、SocketAsyncEventArgsReadAsync/WriteAsync、Task 導向
適用場景自訂協定、高效能、UDP、原始 Socket標準 TCP 文字/二進位協定、快速開發

四、實務建議

  1. 生產環境請使用非同步模式:AcceptAsync、ReceiveAsync、SendAsync 或 Task 版本,避免阻塞執行緒。
  2. 訊息框架:TCP 是串流無邊界,需自行定義長度前綴、分隔符或固定長度。
  3. 例外處理:網路斷線、逾時、重置連線皆會拋出 SocketException / IOException,需完整捕獲並重連邏輯。
  4. 資源釋放:實作 IDisposable,確保 Socket、Stream、Reader/Writer 正確關閉。
  5. 安全性:敏感資料請使用 SslStream 加密傳輸。

結語

掌握 Socket 基礎與高階 TCP 串流兩種模式,可因應不同專案需求。初學者建議先從 TcpListener/Client 入手,熟悉網路程式設計流程後,再深入 Socket 進行效能調優與自訂協定開發。

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