Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
bind()的成员字节顺序为struct sockaddr__C_Sockets_Endianness - Fatal编程技术网

bind()的成员字节顺序为struct sockaddr_

bind()的成员字节顺序为struct sockaddr_,c,sockets,endianness,C,Sockets,Endianness,我正在学习socket编程,我感到很困惑,因为我的学习材料中不一致地使用了htons()和函数族。我目前正在阅读的代码段如下: 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:

我正在学习socket编程,我感到很困惑,因为我的学习材料中不一致地使用了
htons()
和函数族。我目前正在阅读的代码段如下:

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;
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);
下一个示例位于同一个已知站点,其代码段如下:

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;
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\u inet.sin\u port
,而第二种情况下
htons()

问题

为什么
ntohs()
htons()
都不用于
adr\u inet.sin\u系列

注意到的站点没有解释为什么在各自的示例中使用
ntohs()
htons()
;它只说“注意”所述功能的使用

我理解端序,网络字节顺序是大端序。我的问题更多的是,您希望在网络中的
成员中何时使用
结构sockaddr\u,而不是主机字节顺序?在第二个代码示例中,
.sinu port
在被传递到
bind()
之前被设置为网络字节顺序。我可以看到以网络或主机字节顺序向该函数传递数据的情况:
bind()
是一个“与网络相关”的函数,因此它可能需要以网络字节顺序传递数据;另一方面,
bind()
是在主机上执行的,那么为什么不应该接受主机字节顺序的数据呢

为什么在第一个实例中adr_inet.sin_端口上使用ntohs(),而在第二个实例中使用htons()

第一个是错误的,但在实践中无论如何都是有效的

如今,几乎所有机器都使用8位字节和一致的大端字节或一致的小端字节格式。在前一种情况下,
hton[sl]
ntoh[sl]
都是不可操作的;对于后者,两者都颠倒了字节顺序,因此实际上做了相同的事情,即使它们的预期语义不同。因此,在所有可能运行程序的系统上使用错误的方法仍然有效

在设计socket API时,情况并非总是如此;例如,当时流行的PDP-11有点臭名昭著地将(!)又称为“NUXI”顺序用于32位

为什么adr\u inet.sin\u系列上既不使用ntohs()也不使用htons()

在古代,互联网协议栈只是几个(多达十几个)相互竞争的网络技术之一。
family
字段区分这些不同协议的不同类型的
sockaddr*
结构,这些协议并不都遵循big-endian的互联网“规则”,至少不一致。由于
系列
没有通用的网络表示形式,他们只是将其按主机顺序保留,这通常对主机软件更方便

现在,在实践中,除了INET、INET6,有时还有UNIX之外,没有人使用任何家族——后者可以通过在文件系统中使用命名管道来替代,这通常至少是一样好的

为什么在第一个实例中adr_inet.sin_端口上使用ntohs(),而在第二个实例中使用htons()

第一个是错误的,但在实践中无论如何都是有效的

如今,几乎所有机器都使用8位字节和一致的大端字节或一致的小端字节格式。在前一种情况下,
hton[sl]
ntoh[sl]
都是不可操作的;对于后者,两者都颠倒了字节顺序,因此实际上做了相同的事情,即使它们的预期语义不同。因此,在所有可能运行程序的系统上使用错误的方法仍然有效

在设计socket API时,情况并非总是如此;例如,当时流行的PDP-11有点臭名昭著地将(!)又称为“NUXI”顺序用于32位

为什么adr\u inet.sin\u系列上既不使用ntohs()也不使用htons()

在古代,互联网协议栈只是几个(多达十几个)相互竞争的网络技术之一。
family
字段区分这些不同协议的不同类型的
sockaddr*
结构,这些协议并不都遵循big-endian的互联网“规则”,至少不一致。由于
系列
没有通用的网络表示形式,他们只是将其按主机顺序保留,这通常对主机软件更方便

现在,在实践中,除了INET、INET6,有时还有UNIX之外,没有人使用任何家族——后者可以通过在文件系统中使用命名管道来替代,这通常至少是一样好的

为什么
ntohs()
htons()
都不用于
adr\u inet.sin\u系列

adr\u inet.sin\u family
被初始化为
AF\u inet
的值。这在
bits/socket.h
(在您的示例中由
netinet/in.h
调用)中定义为:

然后呢,

#define AF_INET     PF_INET
因此,
AF_INET
只是程序将相关套接字识别为TCP/IP连接的一种方法。它本身实际上并不包含IPv4地址的值,因此不需要对其执行endian转换

另外,请注意,在C的较新迭代中,
netinet/in.h
有一条注释,说明如下:

/* Functions to convert between host and network byte order.

   Please note that these functions normally take `unsigned long int' or
`unsigned short int' values as arguments and also return them.  But
this was a short-sighted decision since on different systems the types
may have different representations but the values are always the same.  */ 
extern uint32_t ntohl (uint32_t __netlong) __THROW __attribute__ ((__const__));
extern uint16_t ntohs (uint16_t __netshort)
        __THROW __attribute__ ((__const__));
extern uint32_t htonl (uint32_t __hostlong)
        __THROW __attribute__ ((__const__));
extern uint16_t htons (uint16_t __hostshort)
        __THROW __attribute__ ((__const__));
而您所引用的网站引用了较旧的
无符号长
无符号短
转换函数的数据类型。因此,在以下情况下,您可能会遇到从该站点运行代码的问题: 您正在使用较新版本的C

为什么
ntohs()
htons()
都不用于
adr\u inet.sin\u系列

adr\u inet.sin\u family
被初始化为
AF\u inet
的值。这在
bits/socket.h
(在您的示例中由
netinet/in.h
调用)中定义为:

然后呢,

#define AF_INET     PF_INET
因此,
AF_INET
只是程序将相关套接字识别为TCP/IP连接的一种方法。它不会起作用