使用 C++Builder 5 的 TServerSocket 與 TClientSocket 元件,快速構建「伺服器/客戶端」雙模式聊天程式。元件內建封裝 WinSock 2 API,開發者只需設定屬性與撰寫事件處理器,即可完成 TCP 連線、收發訊息、錯誤處理等核心功能。
TServerSocket 監聽指定埠,接受多客戶端連線(本範例示範單連線)。TClientSocket 主動連線伺服器 IP/埠。Memo1 輸入訊息,Memo2 顯示收發紀錄。| 元件 | 名稱 | 關鍵屬性設定 |
|---|---|---|
| TServerSocket | ServerSocket1 | Port = 8888、Active = false (由選單控制) |
| TClientSocket | ClientSocket1 | Port = 8888、Active = false、ClientType = ctBlocking (同步阻塞模式,簡化邏輯) |
| TMainMenu | MainMenu1 | 項目:連線、斷開、監聽 |
| TMemo | Memo1 / Memo2 | ReadOnly:Memo2=true,Memo1=false |
| TStatusBar | StatusBar1 | 顯示連線狀態 |
void __fastcall TForm1::ConnectClick(TObject *Sender)
{
if (ClientSocket1->Active) ClientSocket1->Active = false; // 先斷開舊連線
AnsiString ip;
if (InputQuery("連線目標", "請輸入伺服器 IP:", ip) && !ip.IsEmpty()) {
ClientSocket1->Host = ip;
ClientSocket1->Active = true; // 觸發 OnConnect / OnError
}
}
void __fastcall TForm1::ListenClick(TObject *Sender)
{
ListenItem->Checked = !ListenItem->Checked;
ServerSocket1->Active = ListenItem->Checked;
}
void __fastcall TForm1::DisconnectClick(TObject *Sender)
{
ServerSocket1->Active = false;
ClientSocket1->Active = false;
StatusBar1->Panels->Items[0]->Text = "已斷開";
}
void __fastcall TForm1::Memo1KeyDown(TObject *Sender, WORD &Key, TShiftState Shift)
{
if (Key != VK_RETURN) return;
AnsiString msg = Memo1->Lines->Strings[Memo1->Lines->Count - 1];
if (msg.IsEmpty()) return;
if (IsServer) { // 伺服器端:向第一個連線發送
if (ServerSocket1->Socket->ActiveConnections > 0)
ServerSocket1->Socket->Connections[0]->SendText(msg);
} else { // 客戶端:直接發送
ClientSocket1->Socket->SendText(msg);
}
Memo1->Lines->Delete(Memo1->Lines->Count - 1); // 清空輸入行
}
void __fastcall TForm1::ClientSocket1Connect(TObject *Sender, TCustomWinSocket *Socket)
{
IsServer = false;
StatusBar1->Panels->Items[0]->Text = "已連線至 " + Socket->RemoteHost;
}
void __fastcall TForm1::ClientSocket1Error(TObject *Sender, TCustomWinSocket *Socket,
TErrorEvent ErrorEvent, int &ErrorCode)
{
Memo2->Lines->Add("連線錯誤: " + Socket->RemoteHost);
ErrorCode = 0; // 避免預設例外彈窗
ClientSocket1->Active = false;
}
void __fastcall TForm1::ClientSocket1Read(TObject *Sender, TCustomWinSocket *Socket)
{
Memo2->Lines->Add("對方: " + Socket->ReceiveText());
}
void __fastcall TForm1::ServerSocket1Accept(TObject *Sender, TCustomWinSocket *Socket)
{
IsServer = true;
StatusBar1->Panels->Items[0]->Text = "客戶端連入: " + Socket->RemoteAddress;
}
void __fastcall TForm1::ServerSocket1ClientRead(TObject *Sender, TCustomWinSocket *Socket)
{
Memo2->Lines->Add("客戶端: " + Socket->ReceiveText());
}
void __fastcall TForm1::FormCreate(TObject *Sender)
{
IsServer = false;
ServerSocket1->Port = 8888;
ClientSocket1->Port = 8888;
}
ctBlocking,收發在主執行緒同步進行,UI 可能短暫卡頓。生產環境建議改 ctNonBlocking 搭配 OnRead/OnWrite 事件,或將通訊移至工作執行緒。ServerSocket1->Socket->Connections[i] 遍歷所有連線,廣播訊息需迴圈 SendText。SendText/ReceiveText 以換行符分隔,若訊息含換行需自訂協議(長度前綴/分隔符/序列化)。C++Builder 10+ / RAD Studio 仍相容 VCL Socket 元件,但新專案建議考慮:
透過 TServerSocket/TClientSocket 的事件驅動模型,僅需百行代碼即可完成功能完整的 TCP 聊天室。掌握「連線建立 → 狀態標記 → 非同步收發 → 錯誤恢復」四大核心流程,即可舉一反三開發各類客戶端/伺服器應用。