套接字编程中的htons()函数

我是socket编程的新手,我正在尝试理解htons()的操作。 我已经在互联网上阅读了一些这样的教程,例如这个 。 但我无法理解htons()究竟是做什么的。 我尝试了以下代码:

 #include  #include  #include  #include  int main( int argc, char *argv[] ) { int sockfd, newsockfd, portno, clilen; char buffer[256]; struct sockaddr_in serv_addr, cli_addr; int n; /* First call to socket() function */ sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) { perror("ERROR opening socket"); exit(1); } /* Initialize socket structure */ bzero((char *) &serv_addr, sizeof(serv_addr)); portno = 5001; serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = INADDR_ANY; serv_addr.sin_port = htons(portno); /* Now bind the host address using bind() call.*/ if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) { perror("ERROR on binding"); exit(1); } /* Now start listening for the clients, here process will * go in sleep mode and will wait for the incoming connection */ listen(sockfd,5); clilen = sizeof(cli_addr); /* Accept actual connection from the client */ newsockfd = accept(sockfd, (struct sockaddr *)&cli_addr, &clilen); if (newsockfd < 0) { perror("ERROR on accept"); exit(1); } /* If connection is established then start communicating */ bzero(buffer,256); n = read( newsockfd,buffer,255 ); if (n < 0) { perror("ERROR reading from socket"); exit(1); } printf("Here is the message: %s\n",buffer); /* Write a response to the client */ n = write(newsockfd,"I got your message",18); if (n < 0) { perror("ERROR writing to socket"); exit(1); } return 0; } 

在调试时, sin_port的值显示为35091 ,我不明白portno如何从5001更改为35091 。 有人可以解释价值变化的原因吗?

它与字节存储在内存中的顺序有关。 十进制数5001是hex的0x1389 ,因此涉及的字节是0x130x89 。 许多设备以little-endian格式存储数字,这意味着最低有效字节首先出现。 因此,在这个特定的例子中,它意味着在内存中数字5001将被存储为

 0x89 0x13 

htons()函数确保数字以网络字节顺序存储在内存中,首先是最重要的字节。 因此,它将交换组成数字的字节,以便在内存中字节将按顺序存储

 0x13 0x89 

little-endian机器上,交换字节的数字是hex的35091 ,十进制表示法是35091 。 请注意,如果您正在使用big-endian机器,则htons()函数不需要进行任何交换,因为该数字已经以正确的方式存储在内存中。

所有这些交换的根本原因与使用的网络协议有关,这要求传输的数据包使用网络字节顺序。

htonshost-to-network short

这意味着它适用于16位短整数。 即2个字节。

此函数交换短的字节序。

您的电话号码从:

0001 0011 1000 1001 = 5001

更改字节顺序时,它会交换两个字节:

1000 1001 0001 0011 = 35091

htons()函数在主机和网络字节顺序之间转换值。 big-endianlittle-endian以及网络字节顺序之间存在差异,具体取决于您使用的计算机和网络协议。

这样做是为了维持在网络中发送的字节排列(Endianness)。 根据设备的体系结构,数据可以以big endian格式或little endian格式排列在内存中。 在网络中,我们将字节顺序的表示称为网络字节顺序,在我们的主机中,它称为主机字节顺序。 所有网络字节顺序都是大端格式。如果主机的内存计算机体系结构是小端格式,htons()函数就变得必不可少了,但是在大端格式内存架构的情况下,没有必要。你可以找到你的计算机的字节序以下列方式以编程方式: – >

  int x = 1; if (*(char *)&x){ cout<<"Little Endian"< 

然后决定是否使用htons()。但为了避免上述行,我们总是编写htons(),尽管它对基于Big Endian的内存架构没有任何变化。