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

揭開 Socket 編程面紗(四):C++ 服務端監聽線程與客戶端完整流程

     編輯:關於C語言

使用 C++ 原生 Socket API 實現簡單 TCP 服務端與客戶端:服務端啟動監聽線程循環 accept,收到請求回應後繼續監聽;客戶端連接、發送、接收、關閉完整流程。

服務端監聽線程


DWORD WINAPI ListenThread(LPVOID param)
{
    CServerDlg* dlg = (CServerDlg*)param;
    if (listen(dlg->m_Listening, 40) == SOCKET_ERROR) return 0;

    char buf[MAX_PATH];
    while (true)
    {
        SOCKET client = accept(dlg->m_Listening, (sockaddr*)&cliAddr, &len);
        char* ip = inet_ntoa(cliAddr.sin_addr);
        dlg->Receive(client, buf, 100);
        dlg->SetRequestText(buf);

        strcat(buf, " :我是老貓,收到(");
        strcat(buf, ip);
        strcat(buf, ")");
        dlg->Send(client, buf, 100);
    }
    return 0;
}

發送/接收工具函數


int Receive(SOCKET fd, char* buf, int len)
{
    int cnt = len, rc;
    while (cnt > 0)
    {
        rc = recv(fd, buf, cnt, 0);
        if (rc == SOCKET_ERROR) return -1;
        if (rc == 0) return len - cnt;
        buf += rc; cnt -= rc;
    }
    return len;
}

int Send(SOCKET fd, char* buf, int len)
{
    int cnt = len, rc;
    while (cnt > 0)
    {
        rc = send(fd, buf, cnt, 0);
        if (rc == SOCKET_ERROR) return -1;
        if (rc == 0) return len - cnt;
        buf += rc; cnt -= rc;
    }
    return len;
}

客戶端發送流程


void CClientDlg::OnSend()
{
    // 解析 IP、端口、構造 sockaddr_in
    SOCKET s = socket(AF_INET, SOCK_STREAM, 0);
    if (connect(s, (sockaddr*)&local, sizeof(local)) < 0) { ... }

    Send(s, requestBuf, 100);
    memset(replyBuf, 0, MAX_PATH);
    Receive(s, replyBuf, 100);
    // 顯示回應
    closesocket(s);
}

關鍵點

  • 服務端綁定 INADDR_ANY 自動獲取本機 IP,端口 2000。
  • 使用 CreateThread 啟動監聽線程,主線程保持 UI 響應。
  • 本地測試雙端均用 127.0.0.1,局域網測試時客戶端填寫服務端真實 IP。
  • send/recv 可能發送/接收不完全,必須循環調用直到完成或出錯。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved