C语言 套接字编程中的 htons() 函数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19207745/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
htons() function in socket programing
提问by User123422
I am new to socket programming and I am trying to understand the operation of htons(). I've read a few tutorials on the Internet like thisand thisone for instance. But I couldn't understand what htons()does exactly. I tried the following code:
我是套接字编程的新手,我正在尝试了解htons(). 我已经在互联网上阅读了一些教程,例如这个和这个。但我无法理解究竟htons()是什么。我尝试了以下代码:
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
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;
}
The value of sin_portwas shown as 35091while debugging and I don't understand how portnochanged from 5001to 35091. Could someone explain the reason for that change in value please?
的值在调试sin_port时显示为35091,我不明白如何portno从5001变为35091。有人可以解释一下价值变化的原因吗?
回答by brm
It has to do with the order in which bytes are stored in memory. The decimal number 5001is 0x1389in hexadecimal, so the bytes involved are 0x13and 0x89. Many devices store numbers in little-endianformat, meaning that the least significant byte comes first. So in this particular example it means that in memory the number 5001will be stored as
它与字节在内存中的存储顺序有关。十进制数5001是 0x1389十六进制的,所以涉及的字节是0x13和0x89。许多设备以小端格式存储数字,这意味着最低有效字节在前。所以在这个特定的例子中,这意味着在内存中,数字5001将被存储为
0x89 0x13
The htons()function makes sure that numbers are stored in memory in network byte order, which is with the most significant byte first. It will therefore swap the bytes making up the number so that in memory the bytes will be stored in the order
该htons()函数确保数字以网络字节顺序存储在内存中,最高有效字节在前。因此,它将交换组成数字的字节,以便在内存中按顺序存储字节
0x13 0x89
On a little-endianmachine, the number with the swapped bytes is 0x8913in hexadecimal, which is 35091in decimal notation. Note that if you were working on a big-endianmachine, the htons()function would not need to do any swapping since the number would already be stored in the right way in memory.
在little-endian机器上,交换字节的数字是0x8913十六进制的,也就是35091十进制表示法。请注意,如果您在大端机器上工作,则该htons()函数不需要进行任何交换,因为数字已经以正确的方式存储在内存中。
The underlying reason for all this swapping has to do with the network protocols in use, which require the transmitted packets to use network byte order.
所有这些交换的根本原因与正在使用的网络协议有关,它要求传输的数据包使用网络字节顺序。
回答by Salgar
htonsis host-to-network short
htons是 host-to-network short
This means it works on 16-bit short integers. i.e. 2 bytes.
这意味着它适用于 16 位短整数。即 2 个字节。
This function swaps the endianness of a short.
此函数交换 short 的字节序。
Your number starts out at:
您的号码开始于:
0001 0011 1000 1001 = 5001
0001 0011 1000 1001 = 5001
When the endianness is changed, it swaps the two bytes:
当字节序改变时,它交换两个字节:
1000 1001 0001 0011 = 35091
1000 1001 0001 0011 = 35091
回答by xingh1991
the htons()function converts values between host and network byte orders. There is a difference between big-endianand little-endianand network byte order depending on your machine and network protocol in use.
该htons()函数在主机和网络字节顺序之间转换值。big-endian和little-endian以及网络字节顺序之间存在差异,具体取决于您的机器和使用的网络协议。
回答by Kenpachi Zaraki
It is done to maintain the arrangement of bytes which is sent in the network(Endianness). Depending upon architecture of your device,data can be arranged in the memory either in the big endian format or little endian format. In networking, we call the representation of byte order as network byte order and in our host, it is called host byte order. All network byte order is in big endian format.If your host's memory computer architecture is in little endian format,htons() function become necessity but in case of big endian format memory architecture,it is not necessary.You can find endianness of your computer programmatically too in the following way:->
这样做是为了维护在网络中发送的字节的排列(字节序)。根据您设备的架构,数据可以以大端格式或小端格式排列在内存中。在网络中,我们将字节顺序的表示称为网络字节顺序,而在我们的主机中,它称为主机字节顺序。所有网络字节顺序都是big endian格式。如果你主机的内存计算机架构是little endian格式,htons()函数就变得必要了,但在big endian格式内存架构的情况下,它不是必需的。你可以找到你的计算机的endianness也可以通过以下方式以编程方式进行:->
int x = 1;
if (*(char *)&x){
cout<<"Little Endian"<<endl;
}else{
cout<<"Big Endian"<<endl;
}
and then decide whether to use htons() or not.But in order to avoid the above line,we always write htons() although it does no changes for Big Endian based memory architecture.
然后决定是否使用 htons()。但是为了避免上面的行,我们总是写 htons() 虽然它没有改变基于 Big Endian 的内存架构。

