网络字节序

本文介绍了字节序(大端和小端)在计算机存储和网络通信中的概念,提供了在Ubuntu环境下检查字节序的方法,以及使用htonl,ntohl,htons,ntohs等函数进行主机字节序与网络字节序转换的示例。还涵盖了inet_pton和inet_ntop用于地址转换的功能。
摘要由CSDN通过智能技术生成

一,字节序

大端(存储)模式:是指数据的低位字节内容保存在内存的高地址处,而数据的高位字节内容保存在内存的低地址处。

小端(存储)模式:是指数据的低位字节内容保存在内存的低地址处,而数据的高位字节内容,保存在内存的高地址处。

在ubuntn下查看大小端模式
readelf -a 可执行文件 

代码判断当前机器的字节序
#include <stdio.h>
//方法1
int check_sys()
{
    int i=1;
    return (*(char*)&i);
}

//方法2
int check_sys()
{
    union 
    {
        int i;
        char c;
    }un;
    un.i=1;
    return un.c;
    
}
int main()
{
    int ret=check_sys();
    if(ret==1)
    {
        printf("小端\n");
    }
    else
    {
        printf("大端\n");
    }
    return 0;
}
注意:
  1. 网络协议指定了通讯字节序为大端 
  2. 只有在多字节数据(>=2)和非0处理时才需要考虑字节序
  3. 运行在同一台计算机上的进程相互通信时,一般不用考虑字节序
  4. 不同计算机之间通讯,需要转换自己的字节序为网络字节序 

在需要字节序转换的时候一般调用特定字节序转换函数

主机字节序和网络字节序转换API

htonl(发送方调用)
#include <arpa/inet.h>
uint32_t htonl(uint32_t hostint32);
功能32位主机字节序转换成网络字节序数据(IP地址
参数

uint32_t:unsigned int

hostint32:待转换的32位主机字节序数据

返回值成功:返回网络字节序的值

htons(发送方调用)
#include <arpa/inet.h>
uint16_t htons(uint16_t hostint16);
功能16位主机字节序转换成网络字节序数据(端口号
参数

uint16_t:unsigned short int

hostint16:待转换的16位主机字节序数据

返回值成功:返回网络字节序的值
ntohl(接收方调用)
#include <arpa/inet.h>
uint32_t ntohl(uint32_t hostint32);
功能32位网络字节序数据转换成主机字节序数据(IP地址
参数hostint32:待转换的32位网络字节序数据
返回值成功:返回主机字节序的值

ntohs(接收方调用)
#include <arpa/inet.h>
uint16_t ntohs(uint16_t hostint16);
功能16位网络字节序数据转换成主机字节序数据(端口号
参数hostint32:待转换的16位网络字节序数据
返回值成功:返回主机字节序的值
案例
#include <stdio.h>
#include <arpa/inet.h>
int main()
{
    unsigned int a=0x12345678;
    uint32_t b=htonl(a);
    printf("网络字节序:%#x\n",b);
    uint32_t c=ntohl(b);
    printf("主机字节序:%#x\n",c);
    
    uint32_t n_port=htons(8000);
    printf("n_port:%u\n",n_port);
    printf("n_port:%u\n",ntohs(n_port));

    return 0;
}

 

 地址转换函数

inet_pton (发送方,转换完成之后就是大端)

#include <arpa/inet.h>
int inet_pton(int family,const char* strptr,void* addrptr);

 功能:将点分十进制数串转换成32位无符号整数

参数: family:协议族   AF_INET(IPV4)  ,AF_INET6(IPV6)

            strptr:点分十进制数串 (例如:192.168.2.20)

            addrptr:32位无符号整数的地址

返回值:成功返回1,失败返回其他

inet_ntop(接收方)

#include <arpa/inet.h>
int inet_ntop(int family,const char* addrptr,char* strptr,size_t len);

功能:将32位无符号整数转换成点分十进制数串

参数:family:协议族 AF_INET(IPV4)  ,AF_INET6(IPV6)

           addrptr:32位无符号整数

           strptr:点分十进制数串

            len:strptr缓存区长度

返回值:

                成功:则返回字符串的首地址

                失败:返回NULL

案例

#include <stdio.h>
#include <arpa/inet.h>
int main()
{
    //将点分十进制IP地址转成32为无符号32网络字节序
    unsigned int ip;
    inet_pton(AF_INET,"10.7.121.127",&ip);
    printf("ip=%u\n",ip);
    //将无符号32网络字节序转成点分十进制IP地址字符串
    unsigned char ip_buf[16]="";
    inet_ntop(AF_INET,&ip,ip_buf,16);
    printf("ip_buf=%s\n",ip_buf);

    printf("-------------------\n");

    //ip地址存放分析
    unsigned char* p=(unsigned char*)&ip;
    printf("自己实现:%u.%u.%u.%u\n",p[0],p[1],p[2],p[3]);

    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值