using System;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace TcpServerDemo
{
class Program
{
static void Main()
{
const int port = 12345;
var listener = new TcpListener(IPAddress.Any, port);
listener.Start();
Console.WriteLine($"伺服器啟動,監聽 {port}...");
while (true) // 持續接受多個用戶端 (單執行緒示範)
{
using (var client = listener.AcceptTcpClient())
using (var stream = client.GetStream())
using (var reader = new StreamReader(stream, Encoding.UTF8))
using (var writer = new StreamWriter(stream, Encoding.UTF8) { AutoFlush = true })
{
Console.WriteLine($"用戶端連線: {client.Client.RemoteEndPoint}");
while (true)
{
string line = reader.ReadLine();
if (line == null) break; // 用戶端斷線
Console.WriteLine($"收到: {line}");
string reply = line.ToUpper() + " [SERVER ECHO]";
writer.WriteLine(reply);
Console.WriteLine($"回覆: {reply}");
}
}
Console.WriteLine("用戶端斷線,等待下一個...");
}
}
}
}
using System;
using System.IO;
using System.Net.Sockets;
using System.Text;
using System.Windows.Forms;
namespace TcpClientDemo
{
public partial class ClientForm : Form
{
private TcpClient _client;
private StreamReader _reader;
private StreamWriter _writer;
public ClientForm() => InitializeComponent();
private async void btnConnect_Click(object sender, EventArgs e)
{
try
{
_client = new TcpClient();
await _client.ConnectAsync("127.0.0.1", 12345);
var stream = _client.GetStream();
_reader = new StreamReader(stream, Encoding.UTF8);
_writer = new StreamWriter(stream, Encoding.UTF8) { AutoFlush = true };
AppendLog("已連線至伺服器");
btnConnect.Enabled = false;
btnSend.Enabled = true;
_ = ReceiveLoopAsync(); // 火力全開接收迴圈
}
catch (Exception ex)
{
MessageBox.Show($"連線失敗: {ex.Message}");
}
}
private async Task ReceiveLoopAsync()
{
try
{
while (true)
{
string line = await _reader.ReadLineAsync();
if (line == null) break;
AppendLog($"[伺服器] {line}");
}
}
catch (IOException) { /* 連線中斷 */ }
catch (ObjectDisposedException) { /* 已關閉 */ }
finally
{
Invoke(() => { btnConnect.Enabled = true; btnSend.Enabled = false; });
AppendLog("連線已斷開");
}
}
private async void btnSend_Click(object sender, EventArgs e)
{
if (string.IsNullOrWhiteSpace(txtInput.Text)) return;
try
{
await _writer.WriteLineAsync(txtInput.Text);
AppendLog($"[我] {txtInput.Text}");
txtInput.Clear();
}
catch (Exception ex)
{
MessageBox.Show($"發送失敗: {ex.Message}");
}
}
private void AppendLog(string msg)
{
if (InvokeRequired) Invoke(new Action(() => AppendLog(msg)));
else lstLog.Items.Add($"[{DateTime.Now:HH:mm:ss}] {msg}");
}
protected override void OnFormClosing(FormClosingEventArgs e)
{
_writer?.Dispose();
_reader?.Dispose();
_client?.Dispose();
base.OnFormClosing(e);
}
}
}
| 類別 | 角色 | 關鍵方法 |
|---|---|---|
TcpListener | 伺服器監聽器 | Start(), AcceptTcpClient(), AcceptTcpClientAsync() |
TcpClient | 用戶端連線器 | Connect/ConnectAsync, GetStream(), Close() |
NetworkStream | 雙向資料流 | Read/Write/ReadAsync/WriteAsync, Flush() |
StreamReader/Writer | 文字編碼包裝 | ReadLine/WriteLine/ReadLineAsync/WriteLineAsync |
C# Socket 程式設計核心在於 **`TcpListener`/`TcpClient` + `NetworkStream` + `StreamReader/Writer`** 三層封裝。掌握同步/非同步讀寫、連線生命週期管理、編碼處理與例外處理,即可建構穩健的 TCP 通訊應用。高併發、生產級專案建議直接使用 **ASP.NET Core / gRPC / SignalR** 等成熟框架。