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

C++ Builder Socket API 實現 TCP/UDP 雙模式客戶端與伺服器完整原始碼

     編輯:VC 教學

跨平台網路程式設計:Winsock 2.0 原生 API 打造雙協定通訊元件

本文提供完整、可編譯執行的 C++ Builder 專案原始碼,實現同時支援 TCP 與 UDP 的客戶端與伺服器。架構採用非阻塞 Socket + WSAAsyncSelect 事件通知 (客戶端) 與多執行緒 accept/recvfrom 迴圈 (伺服器),展示專業級網路程式設計範式。

共用核心定義

enum PROTO { TCP = 0, UDP = 1 };
#define WM_SOCK WM_USER + 100  // 自定義視窗訊息
const int MAX_BUF = 4096;

客戶端架構 (UDPClient.h/.cpp)

關鍵類別成員

class TLANForm : public TForm {
    // UI 元件:Port, Prot(TCP/UDP), Addr(IP), TxtEdit(收發顯示), Button1(送出)
    SOCKET m_Socket;           // 通訊 Socket
    PROTO m_Protocol;          // 目前協定
    // 訊息映射
    BEGIN_MESSAGE_MAP
        VCL_MESSAGE_HANDLER(WM_SOCK, TMessage, OnRecv)
    END_MESSAGE_MAP(TForm)
};

核心流程:Button1Click (連線/發送)

  1. 驗證 IP/埠口/訊息輸入
  2. WSAStartup(MAKEWORD(2,0)) 初始化 Winsock 2.0
  3. 建立 Socket:socket(AF_INET, SOCK_STREAM/DGRAM, 0)
  4. 綁定本地埠口 (可選,讓 OS 自動分配亦可)
  5. TCP:connect + select 確認連線建立
  6. 發送:send (TCP) / sendto (UDP)
  7. WSAAsyncSelect(m_Socket, Handle, WM_SOCK, FD_READ | FD_CLOSE) 註冊非阻塞事件通知

事件處理:OnRecv

void __fastcall TLANForm::OnRecv(TMessage &Message) {
    switch (WSAGETSELECTEVENT(Message.LParam)) {
        case FD_READ:
            // TCP: recv / UDP: recvfrom
            // 更新 TxtEdit 顯示
            break;
        case FD_CLOSE:
            closesocket(m_Socket);
            break;
    }
}

伺服器架構 (UDPServer.h/.cpp)

雙執行緒設計

  • TListenThread:主監聽執行緒,負責 socket/bind/listen (TCP) 或 recvfrom 迴圈 (UDP)
  • TCommunication:TCP 專用,每個 accept 產生一個工作執行緒處理單一客戶端收發

TListenThread::Execute 核心邏輯

void __fastcall TListenThread::Execute() {
    InitSocket();           // WSAStartup
    CreateListenSocket();   // socket() 依協定
    SetListenSocket();      // setsockopt SO_OPENTYPE
    BindListenSocket();     // bind(INADDR_ANY, Port)
    
    if (m_Protocol == UDP) {
        // UDP 直接收發迴圈
        while (!Terminated) {
            nSize = recvfrom(m_Socket, buf, ..., &from, &nLen);
            if (nSize > 0) { 顯示; sendto(回傳); }
        }
    } else {
        ListenSocket();     // listen(SOMAXCONN)
        FD_ZERO(&FDS); FD_SET(m_Socket, &FDS);
        while (!Terminated) {
            if (select(1, &FDS, 0, 0, 0) > 0) {
                SOCKET client = accept(m_Socket, ...);
                TCommunication *t = new TCommunication(client, FALSE);
                t->WaitFor(); // 同步等待處理完成 (示範用,實際應非同步)
            }
        }
    }
}

TCommunication::Execute (TCP 客戶端處理)

void __fastcall TCommunication::Execute() {
    nSize = recv(m_AcceptSocket, buf, 4096, 0);
    if (nSize > 0) {
        buf[nSize] = '\0';
        // 顯示於主視窗 Memo1 (需同步)
        Sleep(100); // 模擬處理延遲
        send(m_AcceptSocket, buf, nSize, 0); // Echo 回傳
    }
}

關鍵技術細節總結

面向客戶端伺服器
I/O 模型WSAAsyncSelect 事件驅動 (單執行緒)多執行緒 + select/阻塞呼叫
UDP 處理sendto/recvfrom 配合 FD_READ監聽執行緒直接 recvfrom 迴圈
TCP 連線connect + select 非阻塞確認listen + accept 產生工作執行緒
資源清理FormDestroy: closesocket + WSACleanup執行緒析構: closesocket + WSACleanup
錯誤處理WSAGetLastError 彈出訊息框DoError 統一清理 + 訊息框

生產環境強化清單

  1. 封包邊界:TCP 流無邊界,應用層定義長度前綴/分隔符/序列化協定
  2. 心跳機制:定期發送 PING 偵測斷線,TCP 長連線必備
  3. 緩衝區管理:動態擴充/環狀緩衝區,避免固定 4096 截斷/浪費
  4. 執行緒池:伺服器端改用 IOCP / 執行緒池 避免無限建立執行緒
  5. 加密傳輸:整合 OpenSSL / Windows SChannel 實現 TLS 1.3
  6. IPv6 雙棧:AF_INET6 + getaddrinfo 同時支援 IPv4/IPv6
  7. 單元測試:Mock Socket 層,測試協定邏輯與錯誤路徑

此代碼為教學示範,實際專案請依上述清單工程化重構。

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