gpt4 book ai didi

对网络字节顺序和主机字节顺序感到困惑

转载 作者:行者123 更新时间:2023-12-04 10:57:33 26 4
gpt4 key购买 nike

我对 感到非常困惑主机字节序网络字节序 .我知道网络字节顺序是大端。而且我知道在我的情况下主机字节顺序是小端。

那么,如果我正在打印数据,我需要转换为主机字节顺序才能获得正确的值吗?

我的问题是我试图打印 htonl 返回的数据值.这是我的例子:

#include <stdio.h>
#include <netinet/in.h>

int main(int argc, char *argv[])
{
int bits = 12;
char *ip = "132.89.39.0";
struct in_addr addr;
uint32_t network, netmask, last_addr;
uint32_t total_hosts;

inet_aton(ip, &addr);
printf("Starting IP:\t%s\n", inet_ntoa(addr.s_addr));

netmask = (0xFFFFFFFFUL << (32 - bits)) & 0xFFFFFFFFUL;
netmask = htonl(netmask);
printf("Netmask:\t%s\n", inet_ntoa(netmask));

network = addr.s_addr & netmask;
printf("Network:\t%s\n", inet_ntoa(network));

printf("Total Hosts:\t%d\n", ntohl(netmask));

return 0;

}
printf("Total Hosts:\t%d\n", ntohl(netmask));打印正确的值,但打印时带有减号。如果我使用 %u我得到了错误的值。

我哪里错了?

%d 输出为:
Starting IP:    132.89.39.0
Netmask: 255.240.0.0
Network: 132.80.0.0
Total Hosts: -1048576

%u 输出为:
Starting IP:    132.89.39.0
Netmask: 255.240.0.0
Network: 132.80.0.0
Total Hosts: 4293918720

我已经坚持了2天。看似如此简单的事情让我彻底失望了。我不希望任何人解决问题,但朝着正确的方向推进会非常有帮助。

最佳答案

目前有多种系统可以在 little-endian 和 bigendian 之间切换
字节排序,有时在系统重置时,有时在运行时。
作为网络程序员,我们必须处理这些字节顺序差异,因为
网络协议(protocol)必须指定网络字节顺序。例如,在一个 TCP 段中,有
是一个 16 位的端口号和一个 32 位的 IPv4 地址。发送协议(protocol)栈和
接收协议(protocol)栈必须同意这些多字节字段的字节顺序
将被传送。 Internet 协议(protocol)对这些多字节使用大端字节序
整数。
理论上,实现可以将字段存储在主机字节中的套接字地址结构中
顺序,然后在将字段移入和移出时转换为网络字节顺序
协议(protocol)头,让我们不必担心这个细节。但是,无论是历史还是
POSIX 规范说套接字地址结构中的某些字段必须是
以网络字节顺序维护。因此,我们关心的是主机字节顺序之间的转换
和网络字节顺序。我们使用以下四个函数在这两个字节之间进行转换
订单。

 #include <netinet/in.h>
uint16_t htons(uint16_t host16bitvalue) ;
uint32_t htonl(uint32_t host32bitvalue) ;

两者都返回:网络字节顺序中的值
   uint16_t ntohs(uint16_t net16bitvalue) ;
uint32_t ntohl(uint32_t net32bitvalue) ;

两者都返回:主机字节顺序中的值

在这些函数的名称中,h代表主机,n代表网络,s代表缩写,
l 代表长。术语“短”和“长”是来自 Digital VAX 的历史文物
4.2BSD的实现。我们应该将 s 视为 16 位值(例如 TCP 或
UDP 端口号)和 l 作为 32 位值(例如 IPv4 地址)。事实上,在 64 位
数字阿尔法,一个长整数占用 64 位,但 htonl 和 ntohl 函数在
32 位值。
使用这些函数时,我们不关心实际值(big-endian 或 littleendian)
用于主机字节顺序和网络字节顺序。我们必须做的是调用
适当的函数在主机和网络字节顺序之间转换给定值。在
那些与 Internet 协议(protocol)(大端)具有相同字节顺序的系统,这些
四个函数通常定义为空宏。
我们将更多地讨论字节排序问题,关于包含在一个
网络数据包,而不是协议(protocol)头中的字段,
我们还没有定义术语“字节”。我们使用该术语来表示 8 位数量,因为
几乎所有当前的计算机系统都使用 8 位字节。大多数 Internet 标准都使用该术语
八位字节而不是字节表示 8 位数量。这始于 TCP/IP 的早期
因为早期的大部分工作都是在诸如 DEC-10 之类的系统上完成的,它没有使用
8 位字节。
Internet 标准中的另一个重要约定是位排序。在许多互联网
标准,您将看到类似于以下的数据包“图片”(这是第一个
来自 RFC 791 的 IPv4 header 的 32 位):
0                   1                   2                   3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Version| IHL| TYPE OF SERCVICE | TOTAL LENGTH |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

这表示四个字节,按照它们出现在线路上的顺序;最左边的位是
最重要的。但是,编号从分配给最高有效位的零开始。
这是您应该熟悉的符号,以便更容易阅读协议(protocol)
RFC 中的定义。
1980 年代一个常见的网络编程错误是在 Sun 上开发代码
工作站(大端摩托罗拉 68000s)而忘记调用这四个函数中的任何一个。
代码在这些工作站上运行良好,但在移植到 littleendian 时无法运行
机器(例如 VAX)。

关于对网络字节顺序和主机字节顺序感到困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32205546/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com