首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Unix/Linux 網絡編程環境配置:標準頭文件與編譯鏈接指南

     編輯:程式設計綜合問答

問題核心

《Unix Network Programming》示例代碼 `#include "unp.h"` 編譯失敗:找不到頭文件、類型重複定義。`unp.h` 是作者 Stevens 自己封裝的教學頭文件,**非系統標準頭文件**。

標準頭文件替代方案 (POSIX.1g / Single UNIX Specification)


// 替代 unp.h 的標準頭文件組合
#include       // 基礎類型: pid_t, size_t, ssize_t, in_addr_t, in_port_t
#include      // 套接字 API: socket, bind, listen, accept, connect, send, recv
#include      // 網際網路地址結構: sockaddr_in, in_addr, htons, htonl, INADDR_ANY
#include       // IP 地址轉換: inet_pton, inet_ntop, inet_addr, inet_ntoa
#include           // 域名解析: gethostbyname, getaddrinfo, addrinfo, servent
#include          // POSIX 基礎: read, write, close, fork, exec, pipe
#include           // 標準 I/O: printf, perror
#include          // 標準庫: exit, malloc, free
#include          // 字符串: memset, strcmp, strlen
#include           // 錯誤碼: errno, EAGAIN, ECONNREFUSED
#include          // 信號: signal, sigaction
#include        // 進程等待: wait, waitpid
#include      // I/O 多路復用: select, fd_set, FD_*
#include        // 時間: timeval, gettimeofday
#include            // poll (System V)
#include       // epoll (Linux 專用, 高性能)
#include           // 文件控制: fcntl, O_NONBLOCK

常用類型與常量對照 (原 unp.h 定義)

unp.h 定義標準替代所需頭文件
MAXLINE自定義 `#define MAXLINE 4096`—
SA`struct sockaddr` (直接用)``
Listenfd, Connfd`int listenfd, connfd;`—
err_sys, err_quit自定義錯誤處理函數 (見下)—

錯誤處理函數實現 (替代 unp.h 中的 err_*)


#include 
#include 

void err_sys(const char *fmt, ...) {
    va_list ap;
    va_start(ap, fmt);
    vsnprintf(buf, sizeof(buf), fmt, ap);
    va_end(ap);
    perror(buf); // 打印 errno 對應信息
    exit(1);
}

void err_quit(const char *fmt, ...) {
    va_list ap;
    va_start(ap, fmt);
    vsnprintf(buf, sizeof(buf), fmt, ap);
    va_end(ap);
    fprintf(stderr, "%s\n", buf);
    exit(1);
}

編譯命令 (GCC/Clang)


# 基礎編譯
gcc -Wall -Wextra -std=c11 -o daytimetcpcli daytimetcpcli.c

# 鏈接實時庫 (如用 clock_gettime)
gcc -Wall -Wextra -std=c11 -o daytimetcpcli daytimetcpcli.c -lrt

# 啟用線程支持 (pthread)
gcc -Wall -Wextra -std=c11 -pthread -o server server.c

# 靜態分析
clang --analyze -Wall -Wextra daytimetcpcli.c

用戶代碼修正版 (Daytime TCP Client)


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

#define MAXLINE 4096

void err_sys(const char *fmt, ...) {
    va_list ap; va_start(ap, fmt);
    char buf[1024];
    vsnprintf(buf, sizeof(buf), fmt, ap);
    va_end(ap);
    perror(buf);
    exit(1);
}

void err_quit(const char *fmt, ...) {
    va_list ap; va_start(ap, fmt);
    char buf[1024];
    vsnprintf(buf, sizeof(buf), fmt, ap);
    va_end(ap);
    fprintf(stderr, "%s\n", buf);
    exit(1);
}

int main(int argc, char **argv) {
    int sockfd, n;
    char recvline[MAXLINE + 1];
    struct sockaddr_in servaddr;

    if (argc != 2) err_quit("usage: %s ", argv[0]);

    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
        err_sys("socket error");

    memset(&servaddr, 0, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(13); // Daytime server port
    if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0)
        err_quit("inet_pton error for %s", argv[1]);

    if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0)
        err_sys("connect error");

    while ((n = read(sockfd, recvline, MAXLINE)) > 0) {
        recvline[n] = 0;
        if (fputs(recvline, stdout) == EOF)
            err_sys("fputs error");
    }
    if (n < 0) err_sys("read error");
    exit(0);
}

學習資源推薦

  • 《Unix Network Programming, Volume 1》 (Stevens) 第 3 版**:經典教材,但示例代碼依賴 `unp.h`,**建議配合《Linux 高性能服務器編程》 (游雙) 或《Linux 多線程服務端編程》 (陳碩) 學習現代 Linux 網絡編程**。
  • man 手冊:`man 2 socket`, `man 7 ip`, `man 3 getaddrinfo` —— 最權威、最新的 API 文檔。
  • Beej's Guide to Network Programming (在線免費):現代風格、跨平台、無非標準依賴,極適合入門。
  • Linux 內核源碼 `include/uapi/linux/`**:終極參考。

最佳回答核心:「unp頭文件不是系統自帶的。是作者自己封裝的。所以你找不到。你可以參考網上其他socket例子。一般只用了規范的頭文件。基本都能編譯通過。」—— 直接指出教材配套庫非標準,指引使用標準頭文件。

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