主機名稱解析
// 1. 解析主機名稱 → IPAddress[]
IPHostEntry entry = Dns.GetHostEntry("www.example.com");
IPAddress[] addresses = entry.AddressList;
// 2. 取得本機主機名稱
string hostName = Dns.GetHostName();
IPHostEntry localEntry = Dns.GetHostEntry(hostName);
// 3. 反向解析 IP → 主機名稱
IPHostEntry rev = Dns.GetHostEntry("192.168.1.100");
Dns.GetHostEntry 現代 API,取代舊版 Resolve/GetHostByName
- 支援 IPv4/IPv6 雙棧
- 可能拋
SocketException(DNS 失敗、逾時)
IPEndPoint:IP + Port 端點
// IPv4
var ep1 = new IPEndPoint(IPAddress.Parse("192.168.1.50"), 8080);
// IPv6
var ep2 = new IPEndPoint(IPAddress.IPv6Loopback, 8080);
// 任意介面綁定
var epAny = new IPEndPoint(IPAddress.Any, 8080); // 伺服端常用
Socket 生命週期:建立 → 綁定 → 監聽 → 接受
using System.Net;
using System.Net.Sockets;
var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
var endPoint = new IPEndPoint(IPAddress.Any, 2020);
socket.Bind(endPoint); // 綁定本機端點
socket.Listen(50); // 進入監聽狀態,backlog=50
Socket client = socket.Accept(); // 阻塞等待客戶端連線
// client.RemoteEndPoint 取得客戶端 IP:Port
Socket 建構函式參數詳解
| 參數 | 常用值 | 說明 |
| AddressFamily | InterNetwork (IPv4), InterNetworkV6 (IPv6) | 定址方案 |
| SocketType | Stream (TCP), Dgram (UDP), Raw | 通訊語意 |
| ProtocolType | Tcp, Udp, IP, ICMP | 具體協定 |
發送資料:Socket.Send 完整流程
string message = "Hello Server";
byte[] data = Encoding.UTF8.GetBytes(message);
// 1. 基本發送(需迴圈確保完整)
int totalSent = 0;
while (totalSent < data.Length) {
int sent = socket.Send(data, totalSent, data.Length - totalSent, SocketFlags.None);
if (sent == 0) throw new SocketException((int)SocketError.ConnectionReset);
totalSent += sent;
}
// 2. NetworkStream 簡化
using (var ns = new NetworkStream(socket, ownsSocket: false)) {
ns.Write(data, 0, data.Length);
}
常見錯誤代碼對照
| SocketError | 常見原因 | 處理 |
| AddressAlreadyInUse | Port 被佔用 | 換 Port、SO_REUSEADDR、等待 TIME_WAIT |
| ConnectionRefused | 伺服端未啟動/防火牆 | 檢查伺服端、防火牆規則 |
| TimedOut | 網路不通/伺服端無回應 | 重試、增加逾時 |
| NetworkUnreachable | 路由/網卡問題 | 檢查網路基礎設施 |
| ConnectionReset | 對端強制關閉 | 重連邏輯、心跳 |
完整客戶端範例
using (var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)) {
var serverEp = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 2020);
client.Connect(serverEp); // 同步連線
string msg = "Test";
byte[] data = Encoding.UTF8.GetBytes(msg);
client.Send(data);
byte[] recvBuf = new byte[1024];
int recv = client.Receive(recvBuf);
Console.WriteLine($"Server reply: {Encoding.UTF8.GetString(recvBuf, 0, recv)}");
}
SO_REUSEADDR 避免 AddressAlreadyInUse
socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
socket.Bind(endPoint);
允許立即重用處於 TIME_WAIT 狀態的端口,開發/測試環境必加。