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

C++Builder 5 實現 TCP/IP 網路聊天室完整教學

     編輯:關於C++

專案概覽

使用 C++Builder 5 的 TServerSocket 與 TClientSocket 元件,快速構建「伺服器/客戶端」雙模式聊天程式。元件內建封裝 WinSock 2 API,開發者只需設定屬性與撰寫事件處理器,即可完成 TCP 連線、收發訊息、錯誤處理等核心功能。

架構設計

  • 伺服器端:TServerSocket 監聽指定埠,接受多客戶端連線(本範例示範單連線)。
  • 客戶端:TClientSocket 主動連線伺服器 IP/埠。
  • 共用介面:單一表單切換角色,Memo1 輸入訊息,Memo2 顯示收發紀錄。

元件佈局與關鍵屬性

元件名稱關鍵屬性設定
TServerSocketServerSocket1Port = 8888、Active = false (由選單控制)
TClientSocketClientSocket1Port = 8888、Active = false、ClientType = ctBlocking (同步阻塞模式,簡化邏輯)
TMainMenuMainMenu1項目:連線、斷開、監聽
TMemoMemo1 / Memo2ReadOnly:Memo2=true,Memo1=false
TStatusBarStatusBar1顯示連線狀態

核心事件處理器實作

1. 選單:連線 (客戶端主動發起)

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

2. 選單:監聽 (伺服器啟動/停止)

void __fastcall TForm1::ListenClick(TObject *Sender)
{
    ListenItem->Checked = !ListenItem->Checked;
    ServerSocket1->Active = ListenItem->Checked;
}

3. 選單:斷開 (雙向關閉)

void __fastcall TForm1::DisconnectClick(TObject *Sender)
{
    ServerSocket1->Active = false;
    ClientSocket1->Active = false;
    StatusBar1->Panels->Items[0]->Text = "已斷開";
}

4. 訊息發送:Memo1 按 Enter 鍵觸發

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); // 清空輸入行
}

5. 客戶端事件:連線成功 / 錯誤 / 接收

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

6. 伺服器事件:接受連線 / 接收資料

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

7. 表單建立:初始化狀態

void __fastcall TForm1::FormCreate(TObject *Sender)
{
    IsServer = false;
    ServerSocket1->Port = 8888;
    ClientSocket1->Port = 8888;
}

關鍵技術點補充

  • 阻塞 vs 非阻塞:範例採用 ctBlocking,收發在主執行緒同步進行,UI 可能短暫卡頓。生產環境建議改 ctNonBlocking 搭配 OnRead/OnWrite 事件,或將通訊移至工作執行緒。
  • 多客戶端擴充:ServerSocket1->Socket->Connections[i] 遍歷所有連線,廣播訊息需迴圈 SendText。
  • 訊息邊界:TCP 為串流協議,SendText/ReceiveText 以換行符分隔,若訊息含換行需自訂協議(長度前綴/分隔符/序列化)。
  • 防火牆/NAT:伺服器需開放對應埠;客戶端穿透 NAT 通常無問題,伺服器在 NAT 後需埠映射或 UPnP。

現代化遷移建議

C++Builder 10+ / RAD Studio 仍相容 VCL Socket 元件,但新專案建議考慮:

  1. Indy (TIdTCPServer/TIdTCPClient):功能更豐富,支援 SSL/TLS、指令管線、非同步模型完善。
  2. Boost.Asio / cpp-httplib:跨平台、標準 C++、高效能非同步 I/O。
  3. WebSocket / SignalR:若需瀏覽器互通或即時推播架構。

總結

透過 TServerSocket/TClientSocket 的事件驅動模型,僅需百行代碼即可完成功能完整的 TCP 聊天室。掌握「連線建立 → 狀態標記 → 非同步收發 → 錯誤恢復」四大核心流程,即可舉一反三開發各類客戶端/伺服器應用。

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