本文提供基於 System.Net.Sockets.Socket 類別的完整客戶端/伺服器端程式碼範例,展示同步阻塞式 TCP 通訊基礎模式。適合網路程式設計入門者參考。
using System.Windows.Forms;
using System.Net;
using System.Threading;
using System.Net.Sockets;
using System.Text; // Encoding 命名空間
namespace QQ
{
public partial class Socketclient : Form
{
public Socketclient() { InitializeComponent(); }
private void button1_Click(object sender, EventArgs e)
{
string str = this.textBox1.Text.ToString();
BeginSend(str);
}
private void BeginSend(string str)
{
IPAddress serverIp = IPAddress.Parse("127.0.0.1");
IPEndPoint iep = new IPEndPoint(serverIp, 8000);
byte[] byteMessage;
// 建立 TCP Socket
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Connect(iep); // 同步阻塞連線
byteMessage = Encoding.ASCII.GetBytes(str); // 字串轉位元組陣列
socket.Send(byteMessage); // 同步阻塞傳送
socket.Shutdown(SocketShutdown.Both); // 關閉雙向傳輸
socket.Close(); // 釋放資源
}
}
}
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Windows.Forms;
namespace QQ
{
public partial class SocketServer : Form
{
Thread myThread;
Socket socket;
private delegate void listbox_show(string str);
listbox_show listboxshow;
public SocketServer()
{
InitializeComponent();
listboxshow = new listbox_show(show);
}
private IPAddress GetServerIp()
{
IPHostEntry ieh = Dns.GetHostEntry(Dns.GetHostName()); // 取得本機 IP
return ieh.AddressList[0];
}
private void BeginListen()
{
IPAddress ip1 = GetServerIp();
IPEndPoint iep = new IPEndPoint(ip1, 8000);
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Bind(iep); // 綁定本機端點
byte[] byteMessage = new byte[1000];
while (true)
{
try
{
socket.Listen(5); // 開始監聽,佇列長度 5
Socket clientSocket = socket.Accept(); // 同步阻塞等待連線
clientSocket.Receive(byteMessage); // 同步阻塞接收資料
string sTime = DateTime.Now.ToShortDateString();
string msg = sTime + ": " + "Message from: ";
msg += clientSocket.RemoteEndPoint.ToString() + Encoding.Default.GetString(byteMessage);
// 跨執行緒更新 UI:Invoke 委派
this.listBox1.Invoke(listboxshow, msg);
}
catch (System.Exception ex)
{
MessageBox.Show(ex.Message.ToString());
}
}
}
private void show(string str)
{
this.listBox1.Items.Add(str);
}
private void button1_Click(object sender, EventArgs e)
{
try
{
myThread = new Thread(new ThreadStart(BeginListen));
myThread.Start(); // 背景執行緒啟動監聽
this.button1.Enabled = false;
}
catch (System.Exception er)
{
MessageBox.Show(er.Message, "完成", MessageBoxButtons.OK, MessageBoxIcon.Stop);
}
}
}
}
| 參數 | 值 | 說明 |
|---|---|---|
| AddressFamily | InterNetwork | IPv4 網際網路協定 |
| SocketType | Stream | 串流式、可靠、雙向 (TCP) |
| ProtocolType | Tcp | 傳輸控制協定 |
Connect()、Send()、Accept()、Receive() 皆為同步阻塞呼叫while(true) 迴圈 Accept() → Receive() → Invoke() 更新 UI// 定義委派
private delegate void listbox_show(string str);
listbox_show listboxshow = new listbox_show(show);
// 背景執行緒中呼叫
this.listBox1.Invoke(listboxshow, msg);
// UI 執行緒實際執行
private void show(string str) { this.listBox1.Items.Add(str); }
原則:Windows Forms 控制項只能在建立它們的執行緒 (UI 執行緒) 存取,跨執行緒必須用 Control.Invoke/BeginInvoke。
Encoding.ASCII.GetBytesEncoding.Default.GetString (系統預設編碼,通常為 ANSI)Encoding.UTF8 避免中文亂碼BeginConnect/EndConnect, BeginSend/EndSend, BeginAccept/EndAccept, BeginReceive/EndReceive — 不阻塞執行緒,支援高併發本範例展示最基礎的同步阻塞 Socket 程式設計模式。實務開發中,請根據併發需求選擇非同步模式或成熟網路框架 (如 DotNetty, SignalR, gRPC)。