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 網路程式設計:主機資訊與服務查詢函數詳解

編輯:Linux 教學

一、位元組序轉換函數

不同 CPU 架構(x86 為 Little-Endian,網路序為 Big-Endian)導致資料表示差異,Linux 提供四個標準函數統一轉換:

函數說明
htonl()主機長整數 → 網路長整數
htons()主機短整數 → 網路短整數
ntohl()網路長整數 → 主機長整數
ntohs()網路短整數 → 主機短整數

命名規則:h=host, n=network, s=short, l=long。在填充 sockaddr_in 結構的 sin_port、sin_addr.s_addr 時務必使用。

二、主機名與 IP 位址互轉

1. 核心結構 hostent

struct hostent {
    char  *h_name;        // 官方主機名
    char **h_aliases;     // 別名列表
    int    h_addrtype;    // 位址類型 (AF_INET)
    int    h_length;      // 位址長度 (IPv4 為 4)
    char **h_addr_list;   // IP 位址列表
};
#define h_addr h_addr_list[0]  // 第一個 IP 位址

2. 查詢函數

  • gethostbyname(const char *hostname):域名 → hostent 指標
  • gethostbyaddr(const char *addr, int len, int type):IP 位址(二進位)→ hostent 指標

失敗傳回 NULL,錯誤碼存於 h_errno,可用 hstrerror() 取得說明。

三、點分十進位字串與 32 位元二進位 IP 轉換

  • inet_aton(const char *cp, struct in_addr *inp):字串 "192.168.0.1" → 二進位存入 inp,成功回 1。
  • inet_ntoa(struct in_addr in):二進位 → 靜態字串指標(不可重入,多執行緒慎用)。

現代程式建議使用 inet_pton()/inet_ntop() 支援 IPv6 並具執行緒安全。

四、服務資訊查詢

struct servent {
    char  *s_name;       // 服務官方名稱
    char **s_aliases;    // 別名
    int    s_port;       // 埠號 (網路序)
    char  *s_proto;      // 協議名 (tcp/udp)
};
  • getservbyname(const char *name, const char *proto):服務名 → 結構(如 "http", "tcp" → 80)。
  • getservbyport(int port, const char *proto):埠號 → 結構。

五、綜合範例:命令列解析主機資訊

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <netinet/in.h>

int main(int argc, char **argv) {
    if (argc < 2) {
        fprintf(stderr, "Usage: %s hostname|IP ...\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    struct sockaddr_in addr;
    struct hostent *host;
    char **alias;

    for (argv++; *argv; argv++) {
        // 嘗試視為 IP 位址
        if (inet_aton(*argv, &addr.sin_addr)) {
            host = gethostbyaddr((char *)&addr.sin_addr, 4, AF_INET);
            printf("Address information of IP %s\n", *argv);
        } else { // 視為主機名
            host = gethostbyname(*argv);
            printf("Address information of host %s\n", *argv);
        }

        if (!host) {
            fprintf(stderr, "No address information for %s\n", *argv);
            continue;
        }

        printf("Official name: %s\n", host->h_name);
        printf("Aliases: ");
        for (alias = host->h_aliases; *alias; alias++)
            printf("%s ", *alias);
        printf("\nIP addresses: ");
        for (alias = host->h_addr_list; *alias; alias++)
            printf("%s ", inet_ntoa(*(struct in_addr *)*alias));
        printf("\n\n");
    }
    return 0;
}

編譯與測試

gcc -o hostinfo hostinfo.c
./hostinfo www.google.com 8.8.8.8
Copyright © Windows教程網 All Rights Reserved