WinForms 專案 SocketClient,表單放置:
GroupBox「發送訊息」:Label、TextBox txtMsg、Button btnSendGroupBox「伺服器回饋」:ListBox lbInfousing System.IO;
using System.Net;
using System.Net.Sockets;
public partial class Form1 : Form {
private Socket _socket;
private NetworkStream _ns;
private StreamReader _sr;
private StreamWriter _sw;
// ...
}
private void btnSend_Click(object sender, EventArgs e) {
try {
// 1. 建立 TCP Socket
_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPAddress serverIP = IPAddress.Parse("222.18.142.171"); // 伺服器 IP
int port = 13; // Daytime 協定埠,實際依伺服器而定
// 2. 連線
_socket.Connect(serverIP, port);
// 3. 包裝 NetworkStream + 讀寫器
_ns = new NetworkStream(_socket);
_sr = new StreamReader(_ns);
_sw = new StreamWriter(_ns) { AutoFlush = true }; // 自動 Flush
// 4. 發送訊息
_sw.WriteLine(txtMsg.Text);
// 5. 讀取回應(單行)
string response = _sr.ReadLine();
lbInfo.Items.Add($"Server: {response}");
}
catch (Exception ex) {
MessageBox.Show($"Error: {ex.Message}");
}
}
private void Form1_FormClosed(object sender, FormClosedEventArgs e) {
try {
if (_socket != null && _socket.Connected) {
_socket.Shutdown(SocketShutdown.Both); // 禁用收發
}
}
finally {
_sr?.Dispose();
_sw?.Dispose();
_ns?.Dispose();
_socket?.Close(); // 釋放非受控資源
_socket?.Dispose();
}
}
Connect、ReadLine 會阻塞 UI 執行緒,實務上應用 async/await 或 BeginConnect/EndConnect 非同步模式。ReadLine 假設以換行符分隔。自訂協定需自行處理黏包/拆包(長度前綴、分隔符、固定長度)。StreamReader/Writer 預設 UTF-8,雙方需一致。SocketException、IOException、ObjectDisposedException,需分別捕獲。TcpListener、AcceptSocket、讀寫迴圈,支援多客戶端可用 ThreadPool 或 async。
// 使用 System.Net.Sockets + async/await
using var client = new TcpClient();
await client.ConnectAsync("222.18.142.171", 13);
using var stream = client.GetStream();
using var writer = new StreamWriter(stream) { AutoFlush = true };
using var reader = new StreamReader(stream);
await writer.WriteLineAsync(txtMsg.Text);
string response = await reader.ReadLineAsync();
lbInfo.Items.Add($"Server: {response}");