Unix网络编程-套接字地址结构

套接字地址结构

每个协议族都定义他的套接字地址结构。这些结构的名字均以sockaddr_开头,并以对每个协议族的唯一后缀尾。

IPV4套接字地址结构

定义在<netinet/in.h>头文件中,他以sockaddr_in命名。

typedef  uint16_t    in_port_t;

typedef  uint32_t    in_addr_t;

typedef  unsigned short  int    sa_family_t;

struct in_addr {

            in_addr_t  s_addr;  // 32-bit  IPV4 address    network byte order

};

struct sockaddr_in {

            uint8_t        sin_len;  // length of structure  16  OSI协议添加

            sa_family      sin_family;

            in_port_t      sin_port;

            structin_addr  sin_addr;

            char            sin_zero[8];

};

(1)长度字段sin_len是为增加对OSI协议的支持而随4.3BSD-Reno添加的;并不是所有的厂家都支持套接字地址结构的长度字段,而且POSIX规范也不要求有这个成员

(2)POSIX规范只需要这个结构中的3个字段:sin_family、sin_addr和sin_port;对于符合POSIX的实现来说,定义额外的结构字段是可以接受的 

(3)IPv4地址和TCP或UDP端口号在套接字地址结构中总是以网络字节序来存储

(4)sin_zero字段未曾使用,不过在填写这种套接字结构地址时,我们总是把该字段置为0;

通用套接字地址结构                                                                 

当作为一个参数传递给任何套接字函数时,套接字地址结构总是以指针的形式来传递。然而以这样的指针作为参数,就必需能够处理任何协议族的套接字地址结构。                                 

在有了ANSI C后解决办法很简单:void* 通用指针类型就可以。然而套接字函数时在ANSI C之前定义的,在1982年采用的办法时在<sys/socket.h>头文件中定义

一个通用的套接字地址结构。Linux  (/usr/include/bits/sockaddr.h) 

struct sockaddr { 

        uint8_t          sa_len;

        sa_family      sa_family;

        char          sa_data[14];

};                                                                                           

比如:bind函数原型         

        int  bind(int,struct sockaddr* ,socklen_t);       

因此,第二个参数就必须强制转换    ,如下所示: 

        struct  sockaddr_in  serv_addr;   

        bind(sockfd,(struct sockaddr*)&serv_addr,sizeof(serv_addr));   

IPV6套接字地址结构       

IPV6套接字地址结构在<netinet/in.h>头文件中

struct in6_addr {

    uint8_t    s6_addr[16];  // 128-bit IPV6 address  network byte order

};   

#define      SIN6_LEN   

struct sockaddr_in6 {

        uint8_t          sin6_len;  // length of this structure

        sa_family_t      sin6_family; // AF_INET6 

        in_port_t        sin6_port;  // network byte  order 

        uint32_t        sin6_flowinfo;

        structin6_addr  sin6_addr;

        uint32_t        sin6_scope_id; 

};         

(1)如果系统支持套接字地址结构中的长度字段,那么SIN6_LEN常值必须定义       

(2)IPV6的地址族时AF_INET6,而IPV4的地址族是AF_INET     

新的通用套接字地址结构     

作为IPV6套接字API的一部分而定义了新的通用套接字地址结构克服了现有struct sockaddr的一些缺点。新的struct sockaddr_storage足以容纳系统所支持的任何套接字   

地址结构。Sockaddr_storage结构在<netinet/in.h>头文件中定义. Linux (/usr/include/bits/socket.h)

struct  sockaddr_storage{

            uint8_t          ss_len;  // length of this struct

            sa_family_t      ss_family;  // addrress family : AF_XXX

            char              __ss_padding[_SS_PADSIZE];    // 128 - XXX

            unsigned longint  __ss_align;

    };     

(1)如果系统支持的任何套接字地址结构有对齐需要,那么sock_storage能够满足最苛刻的对齐要求

(2)该结构足够大,能够容纳系统支持的任何套接字地址结构 

套接字地址比较                                                                     

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容