struct sockaddr_in bind()的成员字节顺序 [英] struct sockaddr_in member byte order for bind()

查看:118
本文介绍了struct sockaddr_in bind()的成员字节顺序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习套接字编程,对我在学习资料中对 htons()和函数族的用法不一致感到困惑。我目前正在阅读此网站,其中包含以下代码段:

I'm learning socket programming and am confused by what I feel is inconsistent use of htons() and family of functions in my learning material. I'm currently reading this site which has the following code segment:

001 1:       struct sockaddr_in adr_inet;
002 2:       int adr_len;
003 3:
004 4:       memset(&adr_inet,0,sizeof adr_inet);
005 5:
006 6:       adr_inet.sin_family = AF_INET;
007 7:       adr_inet.sin_port = ntohs(0);
008 8:       adr_inet.sin_addr.s_addr = ntohl(INADDR_ANY);
009 9:       adr_len = sizeof adr_inet;

在同一站点下方的下一个示例具有以下代码段:

A subsequent example further down at the same noted site has the following code segment:

030 30:      struct sockaddr_in adr_inet;/* AF_INET */
...
042 42:      /* Create an AF_INET address */
043 43:      memset(&adr_inet,0,sizeof adr_inet);
044 44:
045 45:      adr_inet.sin_family = AF_INET;
046 46:      adr_inet.sin_port = htons(9000);
047 47:      memcpy(&adr_inet.sin_addr.s_addr,IPno,4);
048 48:      len_inet = sizeof adr_inet;
049 49:
050 50:      /* Now bind the address to the socket */
051 51:      z = bind(sck_inet,
052 52:          (struct sockaddr *)&adr_inet,
053 53:          len_inet);

问题

为什么 ntohs()首先在 adr_inet.sin_port 上使用,但 htons()在第二个?

Why is ntohs() used on adr_inet.sin_port in the first instance, but htons() in the second?

问题

为什么在 adr_inet上既不使用 ntohs()也不使用 htons()。 sin_family

Why is neither ntohs() nor htons() used on adr_inet.sin_family?

所提到的站点没有解释为什么 ntohs() htons()分别用于示例;

The noted site doesn't explain why ntohs() or htons() are used in their respective examples; it only says to "note the use of" said functions.

我了解字节序,并且网络字节顺序是big-endian顺序。我的问题是关于何时需要网络中的 struct sockaddr_in 的成员还是主机字节顺序?在第二个代码示例中,将 .sin_port 设置为网络字节顺序,然后再传递给 bind()。我可以看到以网络或主机字节顺序将数据传递给此函数的情况: bind()是一个与网络相关的函数,因此也许它需要其数据以网络字节顺序;另一方面, bind()是在主机上执行的,为什么不接受主机字节顺序的数据呢?

I understand endianness and that network byte order is big-endian order. My questions is more about when do you want a struct sockaddr_in's members in network vs. host byte order? In the second code example, .sin_port is set to network byte order before being passed to bind(). I can see the case for passing data to this function in either network or host byte order: bind() is a "network-related" function, so maybe it needs its data in network byte order; on the other hand bind() is executed on the host, so why shouldn't accept data in host byte order?

推荐答案


为什么在第一个实例中将ntohs()用于adr_inet.sin_port,但在第二个实例中使用htons()?

Why is ntohs() used on adr_inet.sin_port in the first instance, but htons() in the second?

第一个是一个错误,但实际上还是可以的。

The first is a mistake, but in practice works anyway.

如今,几乎所有机器都使用8位字节,并且使用一致的big-endian或一致的little-endian格式。在前者上, hton [sl] ntoh [sl] 都是禁止操作的;在后一种 both 上,它们颠倒了字节顺序,因此即使它们的预期语义不同,它们实际上也会做同样的事情。因此,使用错误的代码仍然可以在所有可能在其上运行程序的系统上使用。

Nowadays practically all machines use 8-bit bytes and either consistent big-endian or consistent little-endian formats. On the former both hton[sl] and ntoh[sl] are no-ops; on the latter both reverse the byte order, and thus actually do the same thing even though their intended semantics are different. Thus using the wrong one still works on all systems you're likely to run a program on.

设计套接字API时并非如此,情况并非总是如此。例如,当时流行的PDP-11有点臭名昭著,'middle-endian'(!)也就是32位的'NUXI'顺序。

Back when the socket API was designed this wasn't always the case; for example the then-popular PDP-11 somewhat infamously used 'middle-endian' (!) aka 'NUXI' order for 32-bit.


为什么adr_inet既不使用ntohs()也不使用htons() .sin_family?

Why is neither ntohs() nor htons() used on adr_inet.sin_family?

在古代,Internet协议栈只是几种(最多十几种)竞争性网络技术之一。 family 字段为这些不同的协议区分了不同类型的 sockaddr _ * 结构,这些结构并非都遵循Internet规则对于大端而言,至少不是一直如此。由于没有家庭的通用网络表示形式,因此他们只是按主机顺序放置它-通常对于主机软件更方便。

Again in ancient times the Internet Protocol stack was only one of several (up to a dozen or so) competing network technologies. The family field distinguishes different types of sockaddr_* structures for these different protocols, which did not all follow the Internet 'rule' for big-endian, at least not consistently. As there was no universal network representation for family they just left it in host order -- which is usually more convenient for host software.

如今,实际上除了INET,INET6和UNIX以外,没有人使用任何族,并且可以通过在文件系统中使用命名管道来代替后者,通常至少是一样好。

Nowadays in practice nobody uses any families but INET, INET6, and sometimes UNIX -- and the latter can be replaced by using named pipes in the filesystem which is usually at least as good.

这篇关于struct sockaddr_in bind()的成员字节顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆