linux网络编程中的字节序转换

       首先解释一下字节序的概念,所谓字节序是指多字节数据的存储顺序,比如0x1234要放在0000H和0001H两存储单元,有两种存储方式:大端格式为[0000H]=12,[0001H]=34和小端格式为[0000H]=34,[0001H]=12。

       大端格式:将高位字节数据存储在低地址低位字节数据存储在高地址

       小端格式:将高位字节数据存储在高地址低位字节数据存储在低地址

       如何自身主机的字节序呢?看如下一个小demo你就明白了。可以自己在终端测试一下的,VC6.0也行的。

       int main(int argc, char *argv[])

       {

             union{

                    short temp;

                    char test[sizeof(short)];

             }un_tmp; 

              un_tmp.temp = 0x1234;

              if ((un_tmp.test[0] == 0x12) && (un_tmp.test[1] == 0x34))

                 printf("大端格式:高位字节数据存储在低地址低位字节数据存储在高地址");

              if ((un_tmp.test[0] == 0x34) && (un_tmp.test[1] == 0x12))

                 printf("小端格式:高位字节数据存储在高地址低位字节数据存储在低地址");

              return 0;

       }

       我们知道在网络编程中会涉及到数据的发送接收问题,数据从一台计算机中发送到另一台计算机时有可能两台计算机的字节序不一致,从而导致数据传送错误,而且最关键的问题是你无法确定对方主机使用的字节序,这样,为了防止这种错误的出现,网络协议指定了通讯的字节序为大端格式,而本机对应的字节序不论大端格式还是小端格式都统称为主机序

       ●只有在多字节数据处理时才需要考虑字节序,单字节数据根本不存在高低字节问题

       ●运行在同一台计算机上的进程相互通信时一般不用考虑字节序

       ●异构计算机之间的通讯,发送数据时需要转换自己的字节序为网络字节序(即统一转换为大端)

       异构计算机之间的通讯,接收数据时需要转换网络字节序为主机字节序

      在需要字节序转换时,一般使用linux系统下arpa/inet.h头文件特定的转换函数。具体见如下:

       1. 主机字节序 => 网络字节序

              1.1 将32位主机字节序数据转换成网络字节序数据

               uint32_t htonl(uint32_t hostint32);

              1.2 将16位主机字节序数据转换成网络字节序数据

              uint16_t htons(uint16_t hostint16);

       例:

       int main(int argc, char *argv[])

       {

              int  a = 0x01020304;

              short  b = 0x0102;

              printf("###:htonl(0x%08x)=0x%08x\n" ,a ,htonl(a));

              printf("###:htons(0x%04x)=0x%04x\n" ,b ,htons(b));

              return 0;

       }

           

       2. 网络字节序 =主机字节序

             2.1 将32位网络字节序数据转换成主机字节序数据

              uint32_t ntohl(uint32_t netint32);

              2.2 将16位网络字节序数据转换成主机字节序数据

             uint16_t ntons(uint16_t netint16);

       例:

       int main(int argc, char *argv[])

       {

              int  a = 0x01020304;

              short  b = 0x0102;

              int  net_int = htonl(a);

              short  net_short = htons(b);

              printf("###:net_int = htonl(0x%08x) = 0x%08x\n" ,a ,net_int);

              printf("###:net_short = htons(0x%04x) = 0x%04x\n" ,b ,net_short);

              printf("###:ntohl(0x%08x)=0x%08x\n" ,net_int ,ntohl(net_int));

              printf("###:ntohs(0x%04x)=0x%04x\n" ,net_short ,ntohs(net_short));

              return 0;

       }

       

       3. 带自动转换字节序的地址转换函数

             3.1 将点分十进制ip字符串strptr转换成对应的网络字节序的32位无符号整数addrptr

             int inet_pton(int family ,const char *strptr ,void *addrptr);  //family是协议栈,一般填AF_INET

              3.2 将主机字节序32位无符号整数addrptr转换成对应的点分十进制ip字符串strptr

              const char *inet_ntop(int family ,const void *addrptr ,char *strptr ,size_t len); 

              len的取值:

              #define INET_ADDRSTRLEN      16

              #define INET6_ADDRSTRLEN    46

       例:

       int main(int argc, char *argv[])

       {

              int  int_addr = 0;

              char  ip[16] = "192.168.1.1";

              char  new_ip[16] = "0.0.0.0";

              printf("###:before inet_pton:int_addr = %d\n" ,int_addr);

              inet_pton(AF_INET ,ip ,&int_addr);

              printf("###:after inet_pton:int_addr = %d\n" ,int_addr);

              printf("###:before inet_ntop:new_ip = %s\n" ,new_ip);

              inet_ntop(AF_INET ,&int_addr ,new_ip ,INET_ADDRSTRLEN);

              printf("###:after inet_ntop:new_ip = %s\n" ,new_ip);

              return 0;

       }

       

       以上几个函数可以在linux终端下编写测试程序进行测试(VC6.0下不能测试,没有头文件),注意要包含对应头文件:#include <arpa/inet.h>

       #include <stdio.h>
       #include <arpa/inet.h>

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: 在 Linux 内核编程,经常需要处理网络数据,因此需要进行网络字节序转换。网络字节序是指在网络上传输数据时使用的字节序,它与主机字节序(本地字节序)不同。 在 x86 架构的计算机,主机字节序是小端序(即低位字节存储在内存的低地址处),而网络字节序是大端序(即高位字节存储在内存的低地址处)。因此,在进行网络数据传输时,需要进行字节序转换Linux 内核提供了一些函数用于进行字节序转换,如: - htons() 和 ntohs() 函数用于将 16 位整数在主机字节序和网络字节序之间转换。 - htonl() 和 ntohl() 函数用于将 32 位整数在主机字节序和网络字节序之间转换。 这些函数都定义在头文件 <arpa/inet.h> 。例如,将一个 16 位整数从主机字节序转换为网络字节序,可以使用以下代码: ```c #include <arpa/inet.h> uint16_t host_number = 12345; uint16_t network_number = htons(host_number); ``` 同样地,将一个 32 位整数从主机字节序转换为网络字节序,可以使用以下代码: ```c #include <arpa/inet.h> uint32_t host_number = 123456789; uint32_t network_number = htonl(host_number); ``` 反之,将一个从网络接收到的数据从网络字节序转换为主机字节序,可以使用以下代码: ```c #include <arpa/inet.h> uint16_t network_number = 0x1234; uint16_t host_number = ntohs(network_number); ``` ```c #include <arpa/inet.h> uint32_t network_number = 0x12345678; uint32_t host_number = ntohl(network_number); ``` 需要注意的是,在进行字节序转换时,必须使用适当的数据类型(如 uint16_t 和 uint32_t),否则可能会出现意外的错误。 ### 回答2: 在Linux内核编程,网络字节序转换是一个常见的操作,因为网络传输使用的是大端字节序(也称为网络字节序),而计算机内部一般使用的是小端字节序。 在进行网络通信时,需要将数据从主机字节序转换为网络字节序,以确保数据的正确传输和解析。同样,在接收到网络数据后,也需要将数据从网络字节序转换为主机字节序,以便正确地处理和使用这些数据。 在Linux内核,提供了一系列的函数来进行字节序转换。其,主要使用的函数为`htonl()`、`htons()`、`ntohl()`和`ntohs()`。它们分别代表主机到网络长整型、主机到网络短整型、网络到主机长整型和网络到主机短整型的转换。 这些函数的命名规则是根据网络字节序的缩写和数据类型的缩写组合而成的。其,h代表主机字节序(host),n代表网络字节序(network),l代表长整型(long),s代表短整型(short)。 使用这些函数进行字节序转换非常简单。例如,要将一个32位整型数从主机字节序转换为网络字节序,可以使用`htonl()`函数,如下所示: ``` uint32_t value = 12345678; uint32_t network_value = htonl(value); ``` 同样地,要将一个网络字节序的32位整型数转换为主机字节序,可以使用`ntohl()`函数,如下所示: ``` uint32_t network_value = 0x1020304; uint32_t host_value = ntohl(network_value); ``` 总之,在Linux内核编程,网络字节序转换是非常常见的操作,可以使用`htonl()`、`htons()`、`ntohl()`和`ntohs()`这些函数来实现。这些函数提供了方便、简单和可靠的方式来进行字节序转换,以确保网络数据的正确传输和处理。 ### 回答3: 在Linux内核编程,网络字节序转换是一个非常重要的概念。网络字节序,也被称为大端字节序,是一种统一的字节序,用于在网络传输数据。而在计算机内部,一般使用的是主机字节序,也就是与处理器相关的字节序。为了在不同主机之间进行网络通信,就需要进行字节序转换Linux内核提供了一系列函数用于进行字节序转换,这些函数主要集在`linux/in.h`和`linux/tcp.h`头文件。其最常用的函数是`htonl`、`htons`、`ntohl`和`ntohs`。它们分别用于将主机字节序转换为网络字节序和将网络字节序转换为主机字节序。 这些函数的原理是通过位操作和移位运算来实现字节序转换。例如,`htonl`函数可以将32位的整数从主机字节序转换为网络字节序,它将高位字节和低位字节进行位置交换。而`ntohl`函数则在将网络字节序转换为主机字节序时,执行与之相反的操作。 在实际的内核编程,我们需要根据具体情况选择合适的字节序转换函数。比如,在编写网络设备驱动程序时,需要将设备收到的网络数据转换为主机字节序进行处理,这时就可以使用`ntohl`和`ntohs`函数。而在将数据发送到网络上时,则需要将主机字节序转换为网络字节序,这时可以使用`htonl`和`htons`函数。 总而言之,通过Linux内核提供的网络字节序转换函数,我们可以方便地进行主机字节序和网络字节序之间的转换,从而实现跨主机的网络通信。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值