sockaddr结构体详解

在网络编程中,sockaddr 结构体用于表示套接字的地址信息。由于不同协议(如 IPv4、IPv6、Unix 域套接字)的地址格式不同,实际使用中通常通过以下三种变体结构来处理不同类型的地址:


1. 通用地址结构:struct sockaddr

  • 用于类型兼容性,所有具体地址结构需强制转换为此类型传递给套接字函数。

  • 字段

    c 复制代码
    struct sockaddr {
        sa_family_t sa_family;  // 地址族(如 AF_INET, AF_INET6, AF_UNIX)
        char         sa_data[14]; // 协议特定地址信息(实际不直接使用)
    };

2. IPv4 地址结构:struct sockaddr_in

  • 用于 IPv4 协议的地址表示。

  • 字段

    c 复制代码
    struct sockaddr_in {
        sa_family_t    sin_family; // 地址族(必须设为 AF_INET)
        in_port_t      sin_port;   // 16 位端口号(需用 `htons()` 转换字节序)
        struct in_addr sin_addr;   // 32 位 IPv4 地址
        char           sin_zero[8]; // 填充字段(通常置零)
    };
    
    struct in_addr {
        in_addr_t s_addr; // IPv4 地址(32 位整数,需用 `inet_pton()` 或 `htonl()` 转换)
    };
  • 示例

    c 复制代码
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_port = htons(8080);
    inet_pton(AF_INET, "192.168.1.1", &addr.sin_addr);
    memset(addr.sin_zero, 0, sizeof(addr.sin_zero));

3. IPv6 地址结构:struct sockaddr_in6

  • 用于 IPv6 协议的地址表示。

  • 字段

    c 复制代码
    struct sockaddr_in6 {
        sa_family_t     sin6_family;   // 地址族(必须设为 AF_INET6)
        in_port_t       sin6_port;     // 16 位端口号(需用 `htons()` 转换)
        uint32_t        sin6_flowinfo; // IPv6 流信息(通常为 0)
        struct in6_addr sin6_addr;     // 128 位 IPv6 地址
        uint32_t        sin6_scope_id; // 接口范围 ID(用于链路本地地址)
    };
    
    struct in6_addr {
        unsigned char s6_addr[16]; // IPv6 地址(128 位)
    };
  • 示例

    c 复制代码
    struct sockaddr_in6 addr6;
    addr6.sin6_family = AF_INET6;
    addr6.sin6_port = htons(8080);
    inet_pton(AF_INET6, "2001:db8::1", &addr6.sin6_addr);

4. Unix 域套接字结构:struct sockaddr_un

  • 用于本地进程间通信(Unix Domain Socket)。

  • 字段

    c 复制代码
    struct sockaddr_un {
        sa_family_t sun_family;        // 地址族(必须设为 AF_UNIX 或 AF_LOCAL)
        char        sun_path[108];     // 文件系统路径名(需唯一且存在)
    };
  • 示例

    c 复制代码
    struct sockaddr_un unix_addr;
    unix_addr.sun_family = AF_UNIX;
    strncpy(unix_addr.sun_path, "/tmp/mysocket", sizeof(unix_addr.sun_path) - 1);

关键注意事项

  1. 类型转换 :具体结构(如 sockaddr_in)在使用时需强制转换为 struct sockaddr*

    c 复制代码
    bind(sockfd, (struct sockaddr*)&addr, sizeof(addr));
  2. 字节序转换 :IPv4/IPv6 的端口号和地址需用 htons()htonl()inet_pton() 转换网络字节序。

  3. 长度参数 :传递地址结构时需指定实际长度(如 sizeof(struct sockaddr_in))。


通过这三种结构体,可以灵活处理不同协议族的网络地址,是网络编程中地址管理的核心基础。

相关推荐
-To be number.wan15 小时前
编译原理第三章:编译器是怎么“认字“的?——词法分析全解析
学习·编辑器
gzkuijing20 小时前
MDI1PRD23B7‑EQ|Novanta IMS一体化RS-485/422步进电机参数、选型要点与典型应用
人工智能·机器学习·编辑器
geovindu1 天前
CSharp: Command Pattern
开发语言·后端·c#·.net·.netcore·命令模式·行为模式
Java后端的Ai之路2 天前
21、Python - 命令模式
开发语言·人工智能·python·命令模式·外观模式
晚风叙码2 天前
Linux(三)apt/yum 软件安装与 vim 编辑器入门指南
linux·编辑器·vim
民乐团扒谱机2 天前
【超详细】PyQt6 实现 AU 风格波形图编辑器:多级缩放与采样点逐级渲染,附全过程代码
开发语言·python·编辑器·pyqt·audition·时域·频谱图
谁刺我心2 天前
【vscode问题】远程remote cpptools导致linux板子cpu爆炸问题
ide·vscode·编辑器
一直C2 天前
Linux网络编程|HTTP协议详解(报文、请求方法、状态码)
linux·http·wireshark·vim·visual studio
Data_Journal4 天前
Scrapyd:分步教程
开发语言·python·microsoft·golang·编辑器·html·iphone
一直C4 天前
Linux应用软件编程|TCP协议与Socket全套编程(三次握手、四次挥手、报文头部、核心机制)
linux·网络协议·tcp/ip·wireshark·vim·visual studio