字节转换函数

本文简单介绍了几个字符排序函数的使用。

大小端字节序

对于一个大于8位的整数,在内存中有两种存储方式:大端字节序及小端字节序;大端字节序是指将二进制数的低字节存放在低地址中;小端字节序则是将低字节放在高地址中。同时,现有的网络协议指定使用大端字节序作为网络传输的字节序,来传送多字节的数据,即网络字节序为大端字节序。
以十进制9999为例,其16位二进制为:0010,0111,0000,1111
对于其小端字节序

对于其大端字节序

因此,如果在使用小端字节序的系统中按大端存储十进制9999的话,读出来的结果为0000,1111,0010,0111,即十进制3879。

字节序转化函数

  • uint16_t htons(uint16_t):用于将按本机字节序存储的16位整数转化为网络字节序;
  • uint16_t ntohs(uint16_t):用于将按网络字节序存储的16位整数转化为本机字节序;
  • uint32_t htonl(uint32_t):用于将按本机字节序存储的32位整数转化为网络字节序;
  • uint32_t ntohl(uint32_t):用于将按网络字节序存储的32位整数转化为本机字节序;
    以上四个函数名中,h,n,s,l分别代表主机,网络,短整数,长整数。前两个函数在网络编程中常用于转换端口号,后面个则是用于转换ipv4地址。

  • int inet_aton(const char, struct in_addr):用于将ASCII字符串转换为网络字节序,将要转换的字符串的指针传递给第一个参数,第二个参数表示结果要存放的地址。若字符串有效则放回1,无效放回0。
  • char *inet_ntoa(struct in_addr*):用于将网络字节序转换为ASCII字符串。
    以上两个函数参数中的struct in_addr是Unix中用来表示网络ipv4地址的结构体。

  • int inte_pton(int, const char, void):用于将ASCII字符串转换为网络字节序,第一个参数指明协议族,可以是AF_INET或AF_INET6。将要转换的字符串的指针传递给第二个参数,第三个参数表示结果要存放的地址。若成功则放回1,字符串无效放回0,其他错误返回-1。
  • const char inte_ntop(int, const void*, char, size_t):用于将网络字节序转换为ASCII字符串。第三个参数为存储结果的地址,不能为空,调用成功时,这个参数就是该函数的返回值;第四个参数表明空间的大小,ipv4一般为16,ipv6一般为46。

Demo

#include <arpa/inet.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>

int main(int argc, char **argv)
{
   printf("This program is used to show the role of several byte order conversion functions\n");
   printf("--------------------------------------------------------------------------------\n");

   uint16_t host_s;
   host_s = atoi(argv[1]);

   printf("Function htons and ntohs:\n");
   uint16_t network_s = htons(host_s);
   printf("\t%hu after fun htons: %hu\n", host_s, network_s);
   host_s = ntohs(network_s);
   printf("\t%hu after fun ntohs: %hu\n", network_s, host_s);

   printf("Function inet_aton and inet_ntoa:\n");
   struct sockaddr_in addr;
   memset(&addr, 0, sizeof(addr));
   char *host_c = argv[2];
   if(inet_aton(host_c, &(addr.sin_addr)));
   {
      printf("\t%s after fun inet_aton: %u\n", host_c, addr.sin_addr.s_addr);
   }

   printf("\t%u after fun inet_ntoa: %s\n", addr.sin_addr.s_addr, 
		   inet_ntoa(addr.sin_addr)); 

   memset(&addr, 0, sizeof(addr));
   printf("Function inet_pton and inet_ntop:\n");
   if((inet_pton(AF_INET, host_c, &(addr.sin_addr.s_addr))) == 1)
   {
      printf("\t%s after fun inet_pton: %u\n", host_c, addr.sin_addr.s_addr);
   }

   printf("\t%u after fun inet_ntop: %s\n", addr.sin_addr.s_addr, 
		   inet_ntop(AF_INET, &(addr.sin_addr.s_addr), host_c, INET_ADDRSTRLEN));

   return 0;
}

结果

This program is used to show the role of several byte order conversion functions
--------------------------------------------------------------------------------
Function htons and ntohs:
	9999 after fun htons: 3879
	3879 after fun ntohs: 9999
Function inet_aton and inet_ntoa:
	127.0.0.1 after fun inet_aton: 16777343
	16777343 after fun inet_ntoa: 127.0.0.1
Function inet_pton and inet_ntop:
	127.0.0.1 after fun inet_pton: 16777343
	16777343 after fun inet_ntop: 127.0.0.1
posted @ 2019-12-19 15:50  孙敏铭  阅读(782)  评论(0编辑  收藏  举报