ntohl()、htonl()、ntohs()、htons()函数用法

ntohl()、htonl()、ntohs()、htons()这几个函数的作用是进行字节顺序的转换,在理解这几个函数之前,我们先了解一下数据的存储。

一、大端存储和小端存储
  1、大端存储:在计算机中,数据是按照字节存储的,多于一个字节的数据,把高字节部分存储在低地址,把低字节部分存储在高地址,这种方式称为大端存储。
       例:0x12345678这个数据,我们一般认为左边是高字节部分,右边是低字节部分,那么在采用大端存储的计算机内部的存储则为下面这样
               低地址:     0x12(高字节)
               >>>>>:     0x34
               >>>>>:     0x56
               高地址:     0x78(低字节)
 即一个整型数据的首地址=高位部分(首地址=低地址)
        典型使用大端存储的厂商是:Motorola
  2、小端存储:多于一个字节的数据,把高字节部分存储在高地址,把低字节部分存放在低地址。
      例:0x12345678这个数据,我们一般认为左边是高字节部分,右边是低字节部分,那么在采用小端存储的计算机内部的存储则为如何下这样
               低地址:     0x78(低字节)
               >>>>>:     0x56
               >>>>>:     0x34
               高地址:     0x12(高字节)
 即首地址部分=低位部分(首地址=低地址)
        典型使用小端存储的厂商是:intel
二、网络传输模式

     网络传输通讯过程中,采用大端在前的方式进行数据发送,对于采用小端模式进行数据存储的系统,要把多字节的数据通过网络传输出去,则需要将数据的字节序进行转换,再进行发送。接收的过程亦然。

三、ntohl()、htonl()、ntohs()、htons()函数

      在这几个函数中n代表net网络,h代表host主机,l代表long长整型,s代表short短整型。这几个函数的作用分别为:

ntohl():将一个无符号长整形数从网络字节顺序转换为主机字节顺序

htonl():将一个无符号长整形数从主机字节顺序转换为网络字节顺序

ntohs():将一个无符号短整形数从网络字节顺序转换为主机字节顺序

htons():将一个无符号短整形数从主机字节顺序转换为网络字节顺序

如下代码

	uint32 a=0x12345678;
	uint32 b;
	b=htonl(a);

运行的结果为b=0x78563412;

  • 11
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
适合初学者 /******* 服务器程序 (server.c) ************/ #include <stdlib.h>; #include <stdio.h>; #include <errno.h>; #include <string.h>; #include <netdb.h>; #include <sys/types.h>; #include <netinet/in.h>; #include <sys/socket.h>; int main(int argc, char *argv[]) { int sockfd,new_fd; struct sockaddr_in server_addr; struct sockaddr_in client_addr; int sin_size,portnumber; char hello[]="Hello! Are You Fine?\n"; if(argc!=2) { fprintf(stderr,"Usage:%s portnumber\a\n",argv[0]); exit(1); } if((portnumber=atoi(argv[1]))<0) { fprintf(stderr,"Usage:%s portnumber\a\n",argv[0]); exit(1); } /* 服务器端开始建立socket 描述符 */ if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1) { fprintf(stderr,"Socket error:%s\n\a",strerror(errno)); exit(1); } /* 服务器端填充 sockaddr 结构 */ bzero(&server_addr,sizeof(struct sockaddr_in)); server_addr.sin_family=AF_INET; server_addr.sin_addr.s_addr=htonl(INADDR_ANY); server_addr.sin_port=htons(portnumber); /* 捆绑sockfd 描述符 */ if(bind(sockfd,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr))== -1) { /******* 客户端程序 client.c ************/ #include <stdlib.h>; #include <stdio.h>; #include <errno.h>; #include <string.h>; #include <netdb.h>; #include <sys/types.h>; #include <netinet/in.h>; #include <sys/socket.h>; int main(int argc, char *argv[]) { int sockfd; char buffer[1024]; struct sockaddr_in server_addr; struct hostent *host; int portnumber,nbytes; if(argc!=3) { fprintf(stderr,"Usage:%s hostname portnumber\a\n",argv[0]); exit(1); } if((host=gethostbyname(argv[1]))==NULL) { fprintf(stderr,"Gethostname error\n"); exit(1); } if((portnumber=atoi(argv[2]))<0) { fprintf(stderr,"Usage:%s hostname portnumber\a\n",argv[0]); exit(1); } /* 客户程序开始建立 sockfd 描述符 */ if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1) { fprintf(stderr,"Socket Error:%s\a\n",strerror(errno)); exit(1); } /* 客户程序填充服务端的资料 */ bzero(&server_addr,sizeof(server_addr)); server_addr.sin_family=AF_INET; server_addr.sin_port=htons(portnumber); server_addr.sin_addr=*((struct in_addr *)host->;h_addr); /* 客户程序发起连接请求 */ if(connect(sockfd,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr) )==-1) { fprintf(stderr,"Connect Error:%s\a\n",strerror(errno)); exit(1); } /* 连接成功了 */ if((nbytes=read(sockfd,buffer,1024))==-1) { fprintf(stderr,"Read Error:%s\n",strerror(errno)); exit(1); } buffer[nbytes]='\0'; printf("I have received:%s\n",buffer); /* 结束通讯 */ close(sockfd); exit(0); }
这几个函数都是用来进行网络字节序和主机字节序之间的转换的。 - `htonl` (Host TO Network Long):将一个 32 位的主机字节序整数转换为网络字节序整数。如果主机字节序是大端字节序,则不做任何改变;如果主机字节序是小端字节序,则将其转换为大端字节序。返回网络字节序整数。 ```c++ #include <arpa/inet.h> uint32_t htonl(uint32_t hostlong); ``` - `htons` (Host TO Network Short):将一个 16 位的主机字节序整数转换为网络字节序整数。如果主机字节序是大端字节序,则不做任何改变;如果主机字节序是小端字节序,则将其转换为大端字节序。返回网络字节序整数。 ```c++ #include <arpa/inet.h> uint16_t htons(uint16_t hostshort); ``` - `ntohl` (Network TO Host Long):将一个 32 位的网络字节序整数转换为主机字节序整数。如果当前主机字节序是大端字节序,则不做任何改变;如果当前主机字节序是小端字节序,则将其转换为小端字节序。返回主机字节序整数。 ```c++ #include <arpa/inet.h> uint32_t ntohl(uint32_t netlong); ``` - `ntohs` (Network TO Host Short):将一个 16 位的网络字节序整数转换为主机字节序整数。如果当前主机字节序是大端字节序,则不做任何改变;如果当前主机字节序是小端字节序,则将其转换为小端字节序。返回主机字节序整数。 ```c++ #include <arpa/inet.h> uint16_t ntohs(uint16_t netshort); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值