字节序的多种转换函数

1.最常用的大小端转换函数

uint32_t htonl(uint32_t hostlong);

uint16_t htons(uint16_t hostshort);

uint32_t ntohl(uint32_t netlong);

uint16_t ntohs(uint16_t netshort);

h表示host,指小端,n表示network指大端,l表示32位长整数,s表示16位短整数。

注意:32位是用来转换IP地址的,16位是用来转换端口号的

使用平台:linux和windows

2.linux专门的转换函数

       64字节主机转网络:htobe64(uint64_t data)

       64字节网络转主机:be64toh(uint64_t data)

       32字节主机转网络:htobe32(uint32_t data)

       32字节网络转主机:be32toh(uint32_t data)

       16字节主机转网络:htobe16(uint16_t data)

       16字节网络转主机:be16toh(uint16_t data)

使用平台:linux

3.封装好的函数可以实现域名解析,大小端转换以及点分十进制和字符串之间的转换

int getaddrinfo(const char *hostname, 
                const char *service, 
                const struct addrinfo *hints, 
                struct addrinfo **result );

通俗一点理解就是给了域名或者IP地址,以及端口号,可以自动生成socket结构体。

hostname:主机名(域名)或者地址串(IPv4的点分十进制或者IPv6的十六进制)

service:服务名或者端口号

hints:对返回值的限制要求结构体,其中包括了socket函数会用到的family,type,protocol,也有sockaddr_in结构体中需要的sin_family。

具体结构如图所示:

struct addrinfo {
    int              ai_flags;
    int              ai_family;//socket的第一个参数
    int              ai_socktype;//socket的第二个参数
    int              ai_protocol;//socket的第三个参数
    socklen_t        ai_addrlen;//connect和bind的第三个参数
    struct sockaddr *ai_addr;//connect和bind的第二个参数
    char            *ai_canonname;
    struct addrinfo *ai_next;
};

result:就是一个指向addrinfo的链表可以使用每一个addrinfo中的信息去创建套接字和绑定监听

注意:hints和result是同一个结构体,但是hints是输入参数,需要填充比如family,flags,socktype等信息,而result会根据hints中的信息,得到对应的套接字函数需要的信息和结构体,这过程中就封装了很多套接字函数初始化的步骤,而大小端转换也在其中。

想要通过套接字地址结构获取IP地址,可以使用getnameinfo函数,刚好和 getaddrinfo是相反的。

int getnameinfo(const struct sockaddr *sockaddr, 
                socklen_t addrlen, 
                char *host, 
                size_t hostlen, 
                char *serv, 
                size_t servlen, 
                int flags);

sockaddr:指向包含协议地址的套接口地址结构

addrlen:sockaddr结构的长度

host:输出参数,对应的IP地址

hostlen:所允许的最大输出字符长度

 

具体详见CSAPP第11章的tiny server和udp的第11章第6小节

其他注意事项:

字节序转换只有在端口和IP地址处用到,但是后面的数据传输过程当中,并没有使用到。

个人理解为:端口和IP地址是16位或者32为多字节数据,需要大小端转换,但是在数据传输过程中,都是以字符串的形式传输的,字符串中每个字符只有8位,也就是一个字节,无论在大端还是小端,结果都是一样的(这需要对大小端概念有一个比较清晰的理解)

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值