Endianness

Tecy 发布于 21 天前 52 次阅读


字节序转换函数(POSIX 标准)

#include <arpa/inet.h>  // 包含所有转换函数

// 16位整数转换
uint16_t htons(uint16_t hostshort);  // 主机序 -> 网络序 (16位)
uint16_t ntohs(uint16_t netshort);   // 网络序 -> 主机序 (16位)

// 32位整数转换
uint32_t htonl(uint32_t hostlong);   // 主机序 -> 网络序 (32位)
uint32_t ntohl(uint32_t netlong);    // 网络序 -> 主机序 (32位)

使用示例:

#include <stdio.h>
#include <arpa/inet.h>

int main() {
    uint16_t host_port = 0x1234;
    uint32_t host_addr = 0x12345678;

    // 主机序 -> 网络序
    uint16_t net_port = htons(host_port);
    uint32_t net_addr = htonl(host_addr);

    printf("原始端口: 0x%04x -> 网络序: 0x%04x\n", host_port, net_port);
    printf("原始地址: 0x%08x -> 网络序: 0x%08x\n", host_addr, net_addr);

    // 网络序 -> 主机序
    uint16_t orig_port = ntohs(net_port);
    uint32_t orig_addr = ntohl(net_addr);

    printf("还原端口: 0x%04x\n", orig_port);
    printf("还原地址: 0x%08x\n", orig_addr);

    return 0;
}

IP 地址转换函数

#include <arpa/inet.h>

// 文本格式 -> 网络二进制格式
int inet_pton(int af, const char *src, void *dst);

// 网络二进制格式 -> 文本格式
const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);

inet_pton() 返回值:

含义
1转换成功
0输入字符串不是有效的地址格式(src 不包含有效地址)
-1地址族 af 无效(errno 设为 EAFNOSUPPORT

inet_ntop() 返回值:

含义
非 NULL成功,返回指向 dst 的指针(即转换后的字符串)
NULL失败,设置 errno 指示具体错误

使用示例:

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

int main() {
    struct in_addr addr;
    const char *ip = "192.168.0.1";

    // 设置IP地址
    if (inet_pton(AF_INET, ip, &addr) != 1) {
        perror("inet_pton失败");
        return 1;
    }

    // 验证输出
    printf("十六进制: 0x%x\n", addr.s_addr);

    // 转换回可读格式
    char ip_str[INET_ADDRSTRLEN];
    inet_ntop(AF_INET, &addr, ip_str, sizeof(ip_str));
    printf("点分十进制: %s\n", ip_str);

    return 0;
}

核心原则

  • 网络通信统一使用大端序(网络字节序)。
  • 主机内部使用本机字节序
  • 所有跨主机传输的数据必须转换。
  • 网络编程中显式转换所有多字节值。
  • 文件格式定义明确字节序(通常用大端序)。
  • 避免直接传输结构体。
  • 浮点数特殊处理。