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

C# 多網卡環境下 TcpListener 正確監聽綁定策略

     編輯:關於C語言

前言

在多網卡(多 IP)伺服器環境中,C# 的 TcpListener 需正確指定綁定的本地端點(IP + Port)。本文說明如何使用 IPEndPoint 與 IPAddress.Any 實現「監聽所有介面」或「指定單一介面」的靈活部署策略。

核心概念

類別/屬性用途
TcpListenerTCP 伺服器監聽器,提供同步阻塞式 AcceptTcpClient/AcceptSocket
IPEndPoint封裝 IP 位址與連接埠,代表網路端點
IPAddress.Any常數 0.0.0.0,表示綁定所有可用網路介面
LocalEndpoint實際綁定的端點(若建構時指定 Port=0,系統自動分配可查詢此屬性)

基本用法:監聽所有介面

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

public class MultiNicServer
{
    private TcpListener _listener;
    private const int Port = 11000;

    public void Start()
    {
        // 綁定 0.0.0.0:11000(所有介面)
        IPAddress ip = IPAddress.Any; // 等同 new IPAddress(new byte[4])
        IPEndPoint localEP = new IPEndPoint(ip, Port);

        _listener = new TcpListener(localEP);
        _listener.Start(); // 開始監聽,預設回log佇列長度 5

        Console.WriteLine($"伺服器啟動,監聽 {_listener.LocalEndpoint}");

        // 同步阻塞接受迴圈
        while (true)
        {
            TcpClient client = _listener.AcceptTcpClient();
            Console.WriteLine($"客戶端連入: {client.Client.RemoteEndPoint}");
            // 這裡通常啟動新執行緒或 Task 處理 client
            HandleClient(client);
        }
    }

    private void HandleClient(TcpClient client)
    {
        // 實作通訊協定...
        client.Close();
    }

    public void Stop() => _listener?.Stop();
}

進階:指定特定網卡 IP 監聽

// 取得本機所有 IP 位址
IPHostEntry host = Dns.GetHostEntry(Dns.GetHostName());
foreach (IPAddress addr in host.AddressList)
{
    if (addr.AddressFamily == AddressFamily.InterNetwork) // IPv4
        Console.WriteLine($"可用 IPv4: {addr}");
}

// 選擇特定 IP(例如 192.168.1.100)
IPAddress specificIp = IPAddress.Parse("192.168.1.100");
IPEndPoint ep = new IPEndPoint(specificIp, Port);
_listener = new TcpListener(ep);

非同步模式(.NET 4.5+ 推薦)

public async Task StartAsync(CancellationToken ct = default)
{
    _listener = new TcpListener(IPAddress.Any, Port);
    _listener.Start();

    while (!ct.IsCancellationRequested)
    {
        TcpClient client = await _listener.AcceptTcpClientAsync();
        _ = Task.Run(() => HandleClient(client), ct); // 火燒忘記或加入追蹤集合
    }
}

多網卡部署檢查清單

  • ✅ 確認防火牆開放目標 Port(所有介面或特定介面)。
  • ✅ 使用 netstat -an | findstr :11000 驗證監聽狀態(應顯示 0.0.0.0:11000 或特定 IP)。
  • ✅ 若需支援 IPv6,建立雙 TcpListener 分別綁定 IPAddress.IPv6Any。
  • ✅ 生產環境建議啟用 SocketOptionName.ReuseAddress 避免重啟時 TIME_WAIT 延遲。

常見錯誤與解決

補充:取得實際綁定端點資訊

// 若建構時 Port=0,系統自動分配
var listener = new TcpListener(IPAddress.Any, 0);
listener.Start();
IPEndPoint actual = (IPEndPoint)listener.LocalEndpoint;
Console.WriteLine($"實際綁定: {actual.Address}:{actual.Port}");
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
錯誤原因解決
SocketException: 要求的地址無效指定的 IP 不屬於本機任何介面改用 IPAddress.Any 或確認 IP 正確性
Address already in usePort 已被其他程序佔用更換 Port 或啟用 ReuseAddress
只能在單一網卡收到封包綁定特定 IP 而非 Any改用 IPAddress.Any 監聽所有介面