Windows XP Windows 7 Windows 2003 Windows Vista Windows 綜合教學 Linux 系統教學
Windows 10 Windows 8 Windows 2008 Windows NT Windows Server 電腦軟體教學
您现在的位置: Windows教程網 >> Windows教程 >  >> Linux 系統教學 >> Linux 教學

Linux 網路程式設計入門:Socket API、TCP 客戶端/伺服器完整實作與常用除錯指令

編輯:Linux 教學

Linux 強大的網路能力源於 Socket 介面。本文從客戶端/伺服器架構、TCP/UDP 差異、常用除錯指令 (netstat, telnet) 切入,系統講解核心 Socket API:socket、bind、listen、accept、connect、位元組序轉換 (htonl/ntohl)、IP/域名解析 (gethostbyname)、inet_aton/ntoa,並提供可編譯執行的最簡 TCP Echo Server/Client 完整程式碼與 Makefile,帶您跨入網路程式設計大門。

網路程式兩大角色

  • 伺服器: socket → bind → listen → accept 循環等待連線。
  • 客戶端: socket → connect 主動發起連線。

核心 API 速查

int socket(int domain, int type, int protocol);
// domain: AF_INET (IPv4), AF_INET6, AF_UNIX (本機)
// type: SOCK_STREAM (TCP), SOCK_DGRAM (UDP)
// protocol: 通常 0

int bind(int sockfd, struct sockaddr *addr, socklen_t addrlen);
// 綁定本地 IP:port,伺服器用 INADDR_ANY 監聽所有介面

int listen(int sockfd, int backlog);  // 將 socket 轉為被動監聽,backlog 為佇列長度

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
// 阻塞等待連線,成功回傳新的 connected socket fd

int connect(int sockfd, struct sockaddr *addr, socklen_t addrlen);
// 客戶端主動連線指定 IP:port

位元組序轉換 (網路序 = Big Endian)

htonl()/htons()  // Host to Network Long/Short
ntohl()/ntohs()  // Network to Host Long/Short

IP/域名解析


struct hostent *gethostbyname(const char *hostname);  // 域名 → IP 列表
struct hostent *gethostbyaddr(const void *addr, socklen_t len, int type); // IP → 域名
char *inet_ntoa(struct in_addr in);  // 32-bit IP → "a.b.c.d" 字串
int inet_aton(const char *cp, struct in_addr *inp); // "a.b.c.d" → 32-bit IP

完整範例:TCP Echo Server (server.c)


#include 
#include 
#include 
#include 
#include 
#include 
#include 

int main(int argc, char *argv[]) {
    if (argc != 2) { fprintf(stderr, "Usage: %s port\n", argv[0]); exit(1); }
    int port = atoi(argv[1]);
    if (port <= 0) { fprintf(stderr, "Invalid port\n"); exit(1); }

    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) { perror("socket"); exit(1); }

    struct sockaddr_in serv_addr = {0};
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    serv_addr.sin_port = htons(port);

    if (bind(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) {
        perror("bind"); exit(1);
    }
    if (listen(sockfd, 5) < 0) { perror("listen"); exit(1); }

    printf("Server listening on port %d...\n", port);
    while (1) {
        struct sockaddr_in cli_addr;
        socklen_t cli_len = sizeof(cli_addr);
        int connfd = accept(sockfd, (struct sockaddr*)&cli_addr, &cli_len);
        if (connfd < 0) { perror("accept"); continue; }
        printf("Client connected: %s:%d\n", inet_ntoa(cli_addr.sin_addr), ntohs(cli_addr.sin_port));

        char *msg = "Hello from server!\n";
        write(connfd, msg, strlen(msg));
        close(connfd);
    }
    close(sockfd);
    return 0;
}

完整範例:TCP Echo Client (client.c)


#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

int main(int argc, char *argv[]) {
    if (argc != 3) { fprintf(stderr, "Usage: %s hostname port\n", argv[0]); exit(1); }
    char *host = argv[1];
    int port = atoi(argv[2]);

    struct hostent *he = gethostbyname(host);
    if (!he) { fprintf(stderr, "Unknown host %s\n", host); exit(1); }

    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    struct sockaddr_in serv_addr = {0};
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(port);
    memcpy(&serv_addr.sin_addr, he->h_addr_list[0], he->h_length);

    if (connect(sockfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) {
        perror("connect"); exit(1);
    }

    char buf[1024];
    int n = read(sockfd, buf, sizeof(buf)-1);
    if (n > 0) { buf[n] = '\0'; printf("Received: %s", buf); }
    close(sockfd);
    return 0;
}

Makefile


all: server client
server: server.c
    gcc -o server server.c
client: client.c
    gcc -o client client.c
clean:
    rm -f server client

編譯測試


make
./server 8888 &      # 背景執行伺服器
./client localhost 8888
# 或用 telnet localhost 8888 測試
# 用 netstat -an | grep 8888 觀察連線狀態

常用除錯指令

  • netstat -an:顯示所有監聽/連線狀態。
  • telnet host port:手動測試 TCP 連線、發送指令。
  • tcpdump -i eth0 port 8888:封包擷取分析。

掌握 Socket 基礎,即可構建各類網路服務、即時通訊、分散式系統的基石。

Copyright © Windows教程網 All Rights Reserved