字节序的多种转换函数

论坛 期权论坛 编程之家     
选择匿名的用户   2021-6-2 16:19   1423   0

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位,也就是一个字节,无论在大端还是小端,结果都是一样的(这需要对大小端概念有一个比较清晰的理解)

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP