Socket 是網路通訊的基礎建構元件。.NET 提供 System.Net.Sockets 命名空間,支援同步/非同步、TCP/UDP 多種模式。本文由淺入深,示範基礎 Socket、TCP Listener/Client 兩種常見架構,並附上完整的伺服器/用戶端範例。
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)}");
}
}
}
此模式封裝 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();
}
}
| 特性 | 基礎 Socket | TcpListener/Client + Stream |
|---|---|---|
| 控制層級 | 完整控制封包、協定細節 | 封裝良好,專注資料流 |
| 資料處理 | 位元組陣列,需自行處理邊界 | 串流,支援逐行/逐字元讀寫 |
| 非同步支援 | BeginAccept/Receive/Send、SocketAsyncEventArgs | ReadAsync/WriteAsync、Task 導向 |
| 適用場景 | 自訂協定、高效能、UDP、原始 Socket | 標準 TCP 文字/二進位協定、快速開發 |
AcceptAsync、ReceiveAsync、SendAsync 或 Task 版本,避免阻塞執行緒。SocketException / IOException,需完整捕獲並重連邏輯。IDisposable,確保 Socket、Stream、Reader/Writer 正確關閉。SslStream 加密傳輸。掌握 Socket 基礎與高階 TCP 串流兩種模式,可因應不同專案需求。初學者建議先從 TcpListener/Client 入手,熟悉網路程式設計流程後,再深入 Socket 進行效能調優與自訂協定開發。