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

C語言實現極簡 TCP 服務端與客戶端(BSD Socket API 入門)

     編輯:關於C語言

服務端核心流程

  1. socket() 創建監聽套接字
  2. bind() 綁定 IP:PORT
  3. listen() 設置佇列長度
  4. accept() 阻塞等待連接,返回連接套接字
  5. 循環 read()/write() 收發數據
  6. close() 關閉連接與監聽套接字

服務端完整代碼

#include <sys/socket.h> 
#include <netinet/in.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <unistd.h> 

int main() { 
    int listenfd = socket(AF_INET, SOCK_STREAM, 0); 
    struct sockaddr_in srv = {0}; 
    srv.sin_family = AF_INET; 
    srv.sin_addr.s_addr = htonl(INADDR_ANY); 
    srv.sin_port = htons(50002); 
    bind(listenfd, (struct sockaddr*)&srv, sizeof(srv)); 
    listen(listenfd, 23); 

    printf("Server listening on port 50002...\n"); 
    int connfd = accept(listenfd, NULL, NULL); 
    printf("Client connected.\n"); 

    char buf[BUFSIZ]; 
    ssize_t n; 
    while ((n = read(connfd, buf, BUFSIZ)) > 0) { 
        write(STDOUT_FILENO, buf, n); // 直接寫標準輸出 
        write(connfd, "server", 6);   // 固定回應 
    } 
    close(connfd); 
    close(listenfd); 
    return 0; 
}

客戶端核心流程

  1. socket() 創建套接字
  2. 填充服務端 sockaddr_in(IP 從參數 argv[1] 獲取)
  3. connect() 發起連接
  4. 循環 write() 發送標準輸入,read() 接收回顯
  5. close() 關閉

客戶端完整代碼

#include <sys/socket.h> 
#include <netinet/in.h> 
#include <arpa/inet.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 

int main(int argc, char* argv[]) { 
    if (argc < 2) { fprintf(stderr, "Usage: %s \n", argv[0]); exit(1); } 
    int connfd = socket(AF_INET, SOCK_STREAM, 0); 
    struct sockaddr_in srv = {0}; 
    srv.sin_family = AF_INET; 
    srv.sin_port = htons(50002); 
    srv.sin_addr.s_addr = inet_addr(argv[1]); 
    connect(connfd, (struct sockaddr*)&srv, sizeof(srv)); 

    write(connfd, "Hello!", 6); 
    char buf[BUFSIZ]; 
    ssize_t n; 
    while ((n = read(connfd, buf, BUFSIZ)) > 0) { 
        printf("Received %zd bytes: ", n); 
        write(STDOUT_FILENO, buf, n); 
        n = read(STDIN_FILENO, buf, BUFSIZ); // 讀鍵盤輸入 
        write(connfd, buf, n); 
    } 
    close(connfd); 
    return 0; 
}

關鍵細節與常見坑

  • 字節序:端口用 htons,IP 用 htonl/inet_addr 轉網絡序。
  • read 返回值:>0 實際讀取字節數;=0 對端關閉(收到 FIN);=-1 錯誤(需檢查 errno)。
  • 緩衝區殘留:示例用 write(STDOUT_FILENO,...) 避免 printf 格式化導致舊數據顯示。
  • 單次連接:服務端只處理一個客戶端;生產環境需 fork/select/epoll 實現併發。
  • 編譯:gcc server.c -o server,gcc client.c -o client。

運行測試

# 終端 1 
./server 
# 終端 2 
./client 127.0.0.1

總結

本例展示了阻塞式 TCP Socket 的最小化實現,適合理解 socket/bind/listen/accept/read/write/close 調用鏈與數據流向。進階方向:非阻塞 I/O、I/O 多路復用、協議幀設計、錯誤重傳等。本文整理自 51CTO 博客實戰筆記。

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