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();
}
<EOF> 標記結束,實際項目建議:定長頭部+長度字段、或特定分隔符、或序列化框架。Shutdown(Both) 發送 FIN 包,再 Close() 釋放資源。| 異常 | 原因 | 處理 |
|---|---|---|
| SocketException: ConnectionRefused | 服務端未啟動/端口錯誤/防火牆 | 檢查服務端、端口、防火牆規則 |
| SocketException: TimedOut | 網絡不可達/服務端無響應 | 設置 SendTimeout/ReceiveTimeout、檢查網絡 |
| ObjectDisposedException | Socket 已關閉後繼續操作 | 檢查生命週期管理、使用 using |
| ArgumentNullException | 傳入 null 緩衝區/地址 | 參數驗證 |
需雙線程:主線程 Receive 循環,子線程讀取控制台輸入 Send。或用 Select/Poll 多路復用單線程處理。異步模式下 BeginSend/EndSend、BeginReceive/EndReceive 或 await SendAsync/ReceiveAsync 更優雅。