同步 Socket 通訊架構圖
[伺服端] [客戶端]
│ │
├─ new Socket() ├─ new Socket()
├─ Bind(IP, Port) │
├─ Listen(backlog) │
├─ Accept() ──────────────────────────►│ Connect(ServerEP)
│ (阻塞等待) │ (阻塞直到連線成功)
▼ ▼
[雙向通訊] ◄──────────────────────────► [雙向通訊]
│ Send/Receive │ Send/Receive
▼ ▼
├─ Close() ├─ Close()
核心類別:Socket
- TCP/IP 協定堆疊的應用層介面
- 網路通訊的端點,一對通訊需要兩個 Socket
- 傳輸層使用 Port 將資料多工至特定應用程式
Socket 三大類型
| 類型 | SocketType | 特性 |
| Stream Socket | Stream | 雙向、可靠、有序、位元組流、流控 |
| Datagram Socket | Dgram | 雙向、不可靠、資料報、無序/重複 |
| Raw Socket | Raw | 存取底層協定(IP/ICMP/IGMP) |
命名空間與建構
using System.Net;
using System.Net.Sockets;
var socket = new Socket(
AddressFamily.InterNetwork, // IPv4
SocketType.Stream, // TCP
ProtocolType.Tcp // TCP 協定
);
IPEndPoint 端點定義
// 1. IPAddress + Port
var ep1 = new IPEndPoint(IPAddress.Parse("192.168.1.100"), 8080);
// 2. long (IP 數值) + Port
var ep2 = new IPEndPoint(3232235876L, 8080); // 192.168.1.100
伺服端完整流程
// 1. 建立 Socket
var server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
// 2. 綁定本機端點
server.Bind(new IPEndPoint(IPAddress.Any, 8080)); // Any = 0.0.0.0 監聽所有介面
// 3. 開始監聽
server.Listen(100); // backlog: 待接受連線佇列長度
// 4. 接受客戶端連線 (阻塞)
Socket client = server.Accept();
// client.RemoteEndPoint 取得客戶端 IP:Port
// 5. 收發資料
byte[] buffer = new byte[1024];
int received = client.Receive(buffer);
string msg = Encoding.UTF8.GetString(buffer, 0, received);
client.Send(Encoding.UTF8.GetBytes("ACK"));
// 6. 關閉
client.Shutdown(SocketShutdown.Both);
client.Close();
server.Close();
客戶端完整流程
// 1. 建立 Socket
var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
// 2. 連線至伺服端
client.Connect(new IPEndPoint(IPAddress.Parse("192.168.1.100"), 8080));
// 3. 發送資料
client.Send(Encoding.UTF8.GetBytes("Hello Server"));
// 4. 接收回應
byte[] buffer = new byte[1024];
int received = client.Receive(buffer);
Console.WriteLine($"Server: {Encoding.UTF8.GetString(buffer, 0, received)}");
// 5. 關閉
client.Shutdown(SocketShutdown.Both);
client.Close();
同步模式特性與限制
| 特性 | 說明 |
| 阻塞調用 | Accept/Connect/Send/Receive 皆阻塞執行緒 |
| 單執行緒處理 | 一個執行緒一次只能處理一個連線 |
| 程式碼簡單 | 線性流程,易理解除錯 |
| 擴展性差 | 高併發需大量執行緒,資源耗盡 |
| 適用場景 | 低併發、內部工具、教學、舊系統維護 |
遷移至非同步的關鍵點
AcceptAsync / ConnectAsync / SendAsync / ReceiveAsync
- 使用
SocketAsyncEventArgs 避免分配(高效能)
- 或
Task 封裝:Task.Factory.FromAsync
- .NET Core 2.1+
SocketTaskExtensions:AcceptAsync() 回傳 ValueTask
關鍵常數與設定
SocketOptionName.ReuseAddress:立即重用 PORT
SocketOptionName.NoDelay:關閉 Nagle 演算法
SendBufferSize/ReceiveBufferSize:調整緩衝區
SocketShutdown.Both:優雅關閉雙向