在網路程式設計領域,WinSocket API 雖然基礎但複雜度高,讓許多開發者望而卻步。然而,若你使用 C++Builder (BCB) 作為開發平台,內建的 TServerSocket 與 TClientSocket 元件將大幅簡化開發流程,讓新手也能快速上手網路通訊程式的撰寫。
這兩個元件封裝了基本的 WinSocket 程式設計邏輯:TServerSocket 負責伺服器端監聽,TClientSocket 負責客戶端連線。它們本身不直接提供 Socket 連線,而是透過各自的 Socket 屬性(分別為 TServerWinSocket 與 TClientWinSocket)來實際管理連線與資料傳輸。這兩個 Socket 類別皆繼承自 TCustomWinSocket,擁有共同的基礎屬性與方法。
| 屬性/事件 | 類型 | 說明 |
|---|---|---|
| Socket | TServerWinSocket | 最核心屬性,提供實際的 Socket 連線,收發資料皆仰賴此屬性。 |
| Port | Integer | 監聽埠號。若 Service 屬性已指定服務類型(如 HTTP、FTP),則忽略此屬性。 |
| Service | AnsiString | 服務名稱(如 "http", "ftp")。指定後自動對應標準埠號 (HTTP:80, FTP:21)。 |
| ServerType | TServerType | 連線模式:stNonBlocking (非阻塞,事件驅動) 或 stThreadBlocking (阻塞,每連線一執行緒)。 |
| Active | Boolean | 啟動/停止伺服器監聽,等同於呼叫 Open()/Close()。 |
| OnAccept | Event | 有客戶端請求連線時觸發。 |
| OnClientRead / OnClientWrite | Event | 通知伺服器有資料可讀/可寫 (僅 NonBlocking 模式下)。 |
| 屬性/事件 | 類型 | 說明 |
|---|---|---|
| Socket | TClientWinSocket | 核心 Socket 物件,功能對應伺服器端。 |
| Address / Host | AnsiString | 伺服器 IP 位址或主機名稱。 |
| Port / Service | Integer / AnsiString | 連線埠號或服務名稱,用法同伺服器端。 |
| ClientType | TClientType | 連線模式:ctNonBlocking (非阻塞) 或 ctBlocking (阻塞)。 |
| Active | Boolean | 啟動/斷開連線。 |
| OnConnect / OnDisconnect / OnRead / OnWrite | Event | 連線建立、斷開、資料可讀/可寫時觸發。 |
無論伺服器或客戶端,實際資料傳輸皆透過 Socket 物件進行:
Connected (Boolean), LocalAddress/Host/Port, RemoteAddress/Host/PortSendText(), SendBuf(), SendStream()ReceiveText(), ReceiveBuf(), ReceiveLength()Close() (伺服器關閉所有連線,客戶端關閉自身連線)以下示範如何在單一表單上整合伺服器與客戶端功能,透過 CheckBox 切換角色。
| 元件類型 | Name | 關鍵屬性設定 | 用途 |
|---|---|---|---|
| TCheckBox | ckListen | Caption="監聽" | 勾選時啟動伺服器模式 |
| TCheckBox | ckConnect | Caption="連接" | 勾選時啟動客戶端模式 |
| TEdit | edName | Text="無名氏" | 暱稱輸入 |
| TEdit | edTalk | - | 訊息輸入框 |
| TMemo | mmTalk | - | 對話顯示區 |
| TServerSocket | ServerSocket1 | Port=2222 | 伺服器監聽元件 |
| TClientSocket | ClientSocket1 | Port=2222 | 客戶端連線元件 |
| TStatusBar | StatusBar1 | Panels 新增一項 | 狀態提示列 |
| TSaveDialog | sdTalk | DefaultExt="txt", Filter="文字檔|*.txt|所有檔|*.*" | 儲存對話記錄 |
if (ServerSocket1->Active) {
ServerSocket1->Active = false;
ckListen->Checked = false;
StatusBar1->Panels->Items[0]->Text = "";
} else {
ServerSocket1->Active = true;
ckListen->Checked = true;
ClientSocket1->Active = false; // 互斥:啟動伺服器時關閉客戶端
StatusBar1->Panels->Items[0]->Text = "監聽中...";
}
ckConnect->Enabled = !(ckListen->Checked); // 介面互斥控制
AnsiString msg = "伺服器訊息:" + Socket->RemoteHost + " 加入聊天室";
for (int i = 0; i < ServerSocket1->Socket->ActiveConnections; i++) {
ServerSocket1->Socket->Connections[i]->SendText(msg);
}
StatusBar1->Panels->Items[0]->Text = msg;
mmTalk->Lines->Add(msg);
AnsiString msg = Socket->ReceiveText();
mmTalk->Lines->Add(msg);
// 廣播給所有連線中的客戶端
for (int i = 0; i < ServerSocket1->Socket->ActiveConnections; i++) {
ServerSocket1->Socket->Connections[i]->SendText(msg);
}
if (ClientSocket1->Active) {
ClientSocket1->Active = false;
ckConnect->Checked = false;
} else {
AnsiString server = "localhost";
if (InputQuery("連接伺服器", "請輸入主機位址:", server)) {
ClientSocket1->Host = server;
ClientSocket1->Active = true;
ckConnect->Checked = true;
}
}
ckListen->Enabled = !(ckConnect->Checked);
mmTalk->Lines->Add(Socket->ReceiveText());
int lastIdx = mmTalk->Lines->Count - 1;
// 避免收到自己發送並被伺服器轉回的重複訊息
if (lastIdx > 0 && mmTalk->Lines->Strings[lastIdx] == mmTalk->Lines->Strings[lastIdx - 1]) {
mmTalk->Lines->Delete(lastIdx);
}
if (Key == 13) { // Enter 鍵
AnsiString msg = edName->Text + ":" + edTalk->Text;
mmTalk->Lines->Add(msg); // 本地顯示
if (ckListen->Enabled && !ckConnect->Enabled) { // 伺服器模式
for (int i = 0; i < ServerSocket1->Socket->ActiveConnections; i++) {
ServerSocket1->Socket->Connections[i]->SendText(msg);
}
} else { // 客戶端模式
ClientSocket1->Socket->SendText(msg);
}
edTalk->Text = "";
Key = 0; // 避免發出嗶聲
}
// mmTalk.OnChange: 限制最大行數防止記憶體溢位
if (mmTalk->Lines->Count >= 100) mmTalk->Lines->Clear();
// mmTalk.OnDblClick: 雙擊清空
mmTalk->Lines->Clear();
// bbtSave.OnClick: 儲存對話記錄
if (sdTalk->Execute()) mmTalk->Lines->SaveToFile(sdTalk->FileName);
掌握 TServerSocket 與 TClientSocket 的事件驅動模型與 Socket 物件操作,即可快速建構 TCP 通訊應用。此範例展示了基本的聊天室架構,實務上可延伸加入:使用者清單管理、私訊功能、檔案傳輸、加密傳輸 (SSL/TLS) 或整合資料庫記錄等進階功能。C++Builder 的 VCL 架構讓網路程式設計變得直觀高效,是 Windows 平台快速開發網路應用的利器。