【问题标题】:Decide between htons and htonl在 htons 和 htonl 之间做决定
【发布时间】:2017-01-07 19:54:42
【问题描述】:

我已经阅读了this explanationthis manual page 关于htonshtonlntohlntohs 的用法,但是我仍然不完全了解它们的用法(我对套接字很陌生API 和一般的网络编程)。我确实了解大小端序和字节顺序,但我不确定如何在我的聊天应用程序代码中正确实现这些功能,以便它在不同的机器上始终如一地工作(其中一台使用大端序而另一台使用很少)。

我的具体情况的一点背景;我有一个(几乎)可以正常工作的聊天应用程序,并且刚刚使用htons,但经过一些研究,这似乎是不可靠的。我意识到this question 可能看起来很相似,但是我在这里询问一个实现示例,我已经知道这些调用的基本功能。

【问题讨论】:

  • “但经过一些研究,这似乎是不可靠的” 不确定您的意思。请解释一下。
  • 我并不是说这个函数不可靠,我的意思是如果我不使用正确的函数,那么我的程序可能会发送意外数据(错误的字节顺序)。如果我错了,请纠正我,但在我提供的第一个链接上,它是这样说的:“结果是,如果您将一个两字节的短整数从 Intel 机器发送()到 Mac(之前它们也变成了英特尔盒子,我的意思是),一台计算机认为是数字 1,另一台计算机认为是数字 256,反之亦然。"
  • 当您要通过网络从您的主机发送数据时,您可以使用 hton* 进行准备。当您从网络接收到主机的数据时,您使用 ntoh*。如果数据位于 short(或更准确地说,int16_t)中,则选择 s 版本;如果是 long,则选择 l 变体。这有什么令人困惑的?
  • 感谢您解决这个问题。愚蠢的问题,但我应该将它用于所有传输(例如,当我发送任何数据时),因为目前我使用 htons 的唯一实例是将端口号(5000)放入我的 sockaddr_in 结构的 sin_port诠释?
  • 所以如果我有一个结构体,声明如下:sockaddr_in server; 然后inet_pton(AF_INET, "127.0.0.1", &server.sin_addr.s_addr); 分配IP,然后server.sin_port = 5000 分配端口,我想更改IP 参数吗在inet_ptonhtonl("127.0.0.1"),端口设置到htons(5000)?如果是这样,为什么该结构完全通过网络发送?知道服务器详情不只是供客户端使用吗?

标签: c sockets network-programming


【解决方案1】:

这个想法是对整数类型有一些共同的表示。 TCP/IP 使用 NBO,即网络字节排序。不管它是什么(大端或小端或更奇特)发送 16 位整数或 32 位的方法是在发送此类数据之前使用htonshtonl。然后在接收时,您必须使用ntohsntohl 将其转换回您的主机表示:

发送者想发送值uint32_t a,然后发送htonl(a)返回的数据,比如说d。

接收方获取d,应用ntohl(d) 并获得正确的uint32_t 值。

这些只是编码/解码函数。发送方发送代码(v),然后接收方得到解码(代码(v))!你不必知道 code(v) 等于什么(没兴趣)。

如果您觉得它不可靠,这是因为您没有按应有的方式使用它。

【讨论】:

  • 我确实了解这部分,但是为什么有些用户说我应该在将端口号存储在我的服务器结构中时使用它?据我所知,它没有被发送到任何地方,唯一被发送的是包含消息的 char 数组......
  • 你叫什么服务器结构?请记住,在发送消息时,有很多信息会打包您的数据,发送方 ip 信息、接收方 ip 信息等。因此需要以精确的字节顺序给它们。
  • 啊,所以当客户端执行write(sock, message, strlen(message))时,那也是在发送一些数据比如server.sin_port?
  • 当然,如果不是,您的数据如何正确路由到目的地?了解 IP 堆栈的工作方式。
  • 哈哈,我没有想通(阅读我的描述,你会明白为什么)。无论如何感谢您的帮助。
【解决方案2】:

如果您在 2 台计算机之间的网络上发送数据,接收方必须解释数据,以使解释的值与发送方的值相同。

假设发送者在网络上从一个小端机器发送一个 4 字节的 LONG,而接收者的机器是大端机器。在这种情况下,接收者可能会以其他顺序解释这 4 个字节。

函数HtoNxNtoHx 有助于使传输统一,将网络视为大端。对于每种基本数据类型,x 可以取不同的值,代表数据的大小。所以发送者从他的机器发送HtoNl(主机到网络LONG),这个函数会将数据转换为网络解释(即大端)。接收方会执行NtoHl(网络到主机LONG),这个函数会从网络解释转换为自己的机器解释(如果他自己的机器也是大端,NtoHl是身份函数)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-11
    相关资源
    最近更新 更多