首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

C++Builder 網路程式設計:TServerSocket 與 TClientSocket 完整應用指南

     編輯:關於C++

在網路程式設計領域,WinSocket API 雖然基礎但複雜度高,讓許多開發者望而卻步。然而,若你使用 C++Builder (BCB) 作為開發平台,內建的 TServerSocket 與 TClientSocket 元件將大幅簡化開發流程,讓新手也能快速上手網路通訊程式的撰寫。

核心元件架構解析

這兩個元件封裝了基本的 WinSocket 程式設計邏輯:TServerSocket 負責伺服器端監聽,TClientSocket 負責客戶端連線。它們本身不直接提供 Socket 連線,而是透過各自的 Socket 屬性(分別為 TServerWinSocket 與 TClientWinSocket)來實際管理連線與資料傳輸。這兩個 Socket 類別皆繼承自 TCustomWinSocket,擁有共同的基礎屬性與方法。

TServerSocket 關鍵屬性與事件

屬性/事件類型說明
SocketTServerWinSocket最核心屬性,提供實際的 Socket 連線,收發資料皆仰賴此屬性。
PortInteger監聽埠號。若 Service 屬性已指定服務類型(如 HTTP、FTP),則忽略此屬性。
ServiceAnsiString服務名稱(如 "http", "ftp")。指定後自動對應標準埠號 (HTTP:80, FTP:21)。
ServerTypeTServerType連線模式:stNonBlocking (非阻塞,事件驅動) 或 stThreadBlocking (阻塞,每連線一執行緒)。
ActiveBoolean啟動/停止伺服器監聽,等同於呼叫 Open()/Close()。
OnAcceptEvent有客戶端請求連線時觸發。
OnClientRead / OnClientWriteEvent通知伺服器有資料可讀/可寫 (僅 NonBlocking 模式下)。

TClientSocket 關鍵屬性與事件

屬性/事件類型說明
SocketTClientWinSocket核心 Socket 物件,功能對應伺服器端。
Address / HostAnsiString伺服器 IP 位址或主機名稱。
Port / ServiceInteger / AnsiString連線埠號或服務名稱,用法同伺服器端。
ClientTypeTClientType連線模式:ctNonBlocking (非阻塞) 或 ctBlocking (阻塞)。
ActiveBoolean啟動/斷開連線。
OnConnect / OnDisconnect / OnRead / OnWriteEvent連線建立、斷開、資料可讀/可寫時觸發。

TCustomWinSocket 共用核心方法

無論伺服器或客戶端,實際資料傳輸皆透過 Socket 物件進行:

  • 連線狀態: Connected (Boolean), LocalAddress/Host/Port, RemoteAddress/Host/Port
  • 資料發送: SendText(), SendBuf(), SendStream()
  • 資料接收: ReceiveText(), ReceiveBuf(), ReceiveLength()
  • 連線控制: Close() (伺服器關閉所有連線,客戶端關閉自身連線)

實戰範例:簡易區域網路聊天程式

以下示範如何在單一表單上整合伺服器與客戶端功能,透過 CheckBox 切換角色。

表單元件配置

元件類型Name關鍵屬性設定用途
TCheckBoxckListenCaption="監聽"勾選時啟動伺服器模式
TCheckBoxckConnectCaption="連接"勾選時啟動客戶端模式
TEditedNameText="無名氏"暱稱輸入
TEditedTalk-訊息輸入框
TMemommTalk-對話顯示區
TServerSocketServerSocket1Port=2222伺服器監聽元件
TClientSocketClientSocket1Port=2222客戶端連線元件
TStatusBarStatusBar1Panels 新增一項狀態提示列
TSaveDialogsdTalkDefaultExt="txt", Filter="文字檔|*.txt|所有檔|*.*"儲存對話記錄

核心程式碼實作

1. 伺服器啟動/停止邏輯 (ckListen.OnClick)

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); // 介面互斥控制

2. 接受客戶端連線廣播 (ServerSocket1.OnAccept)

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);

3. 接收並轉發訊息 (ServerSocket1.OnClientRead)

AnsiString msg = Socket->ReceiveText();
mmTalk->Lines->Add(msg);
// 廣播給所有連線中的客戶端
for (int i = 0; i < ServerSocket1->Socket->ActiveConnections; i++) {
    ServerSocket1->Socket->Connections[i]->SendText(msg);
}

4. 客戶端連線/斷線邏輯 (ckConnect.OnClick)

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);

5. 客戶端接收訊息去重 (ClientSocket1.OnRead)

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);
}

6. 發送訊息通用邏輯 (edTalk.OnKeyPress, 偵測 Enter 鍵)

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; // 避免發出嗶聲
}

7. 輔助功能:訊息紀錄管理與儲存

// 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 平台快速開發網路應用的利器。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved