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

Winsock 網絡編程入門:TCP 客戶端完整實作與工作區多專案管理

     編輯:VC 教學

客戶端與伺服端核心差異

步驟伺服端客戶端
1. 綁定 IP/Port✅ bind()❌ 不需要
2. 監聽連線✅ listen()❌ 不需要
3. 接受連線✅ accept()❌ 不需要
4. 主動連線❌✅ connect()

Visual Studio 6.0 多專案工作區建立

  1. File → New → Projects 選擇 Win32 Console Application,命名為 Server
  2. 同方案下 Insert → Project 新增 Client 專案
  3. 兩專案皆需連結 Ws2_32.lib:
    專案 → Settings → Link → Object/Library modules 加入 Ws2_32.lib

客戶端完整原始碼 (Console)

#include <Winsock2.h>
#include <stdio.h>

#pragma comment(lib, "Ws2_32.lib")

int main()
{
    // 1. 協商版本
    WSADATA wsaData;
    WORD wVersion = MAKEWORD(2, 2); // 建議使用 2.2
    int err = WSAStartup(wVersion, &wsaData);
    if (err != 0) {
        printf("WSAStartup 失敗: %d\n", err);
        return 1;
    }
    if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) {
        WSACleanup();
        printf("Winsock 2.2 不可用\n");
        return 1;
    }

    // 2. 建立 Socket
    SOCKET sockClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (sockClient == INVALID_SOCKET) {
        printf("socket() 失敗: %d\n", WSAGetLastError());
        WSACleanup();
        return 1;
    }

    // 3. 目標伺服器地址
    sockaddr_in serverAddr = {};
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(27015);
    serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); // 本機測試

    // 4. 連線伺服器
    if (connect(sockClient, (SOCKADDR*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) {
        printf("連線失敗: %d\n", WSAGetLastError());
        closesocket(sockClient);
        WSACleanup();
        return 1;
    }
    printf("已連線至伺服器\n");

    // 5. 接收歡迎訊息
    char recvBuf[128] = {};
    int nRecv = recv(sockClient, recvBuf, sizeof(recvBuf) - 1, 0);
    if (nRecv > 0) {
        recvBuf[nRecv] = '\0';
        printf("收到: %s\n", recvBuf);
    }

    // 6. 發送訊息
    const char* sendMsg = "this is client message";
    send(sockClient, sendMsg, (int)strlen(sendMsg) + 1, 0); // 含結束符
    printf("已發送: %s\n", sendMsg);

    // 7. 清理
    closesocket(sockClient);
    WSACleanup();
    return 0;
}

關鍵點補充

  • 版本協商:建議 MAKEWORD(2,2),支援 IPv6、重疊 I/O 等新特性
  • 錯誤處理:所有 Socket API 失敗時需呼叫 WSAGetLastError() 取得錯誤碼
  • 緩衝區大小:recv 回傳實際收到位元組數,**必須手動加結束符** 才能用 printf("%s")
  • 發送長度:send 第三參數為位元組數,字串常加 +1 發送 \0 方便接收端判斷
  • 阻塞模式:預設為阻塞,recv 無資料時會等待;生產環境常改用非阻塞 + select/WSAAsyncSelect/IOCP

下一步擴展方向

  1. 多執行緒:每連線一執行緒,或執行緒池
  2. GUI 介面:MFC CAsyncSocket 或 CSocket 封裝
  3. 協定設計:定義訊息頭 (長度、類型)、心跳、重連機制
  4. 安全性:整合 OpenSSL 實現 TLS 加密傳輸
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved