在对我的家庭互联网上偶尔出现的网络“失速”进行故障排除时,我发现了戴尔提供的这个技术提示。他们建议使用ping -n
以避免由 DNS 解析引起的停顿。这让我想到,-n
开关实际上做了什么?在我看来,如果您 ping DNS 名称,则需要 DNS 解析,但如果您 ping IP,则不需要。
从手册页:
-n 仅数字输出。不会尝试查找主机地址的符号名称。
如果我 ping 一个 IP 地址,比如ping 8.8.8.8
这里有什么 DNS 查找?做ping -n 8.8.8.8
一些不同的事情吗?
它可能取决于实现。如果在其输出中
ping
没有-n
包含,则可能不包含,这就是区别。但有可能两个输出都不包含字符串。dns.google
ping -n
在我的 Ubuntu 18.04.4 LTS
man 8 ping
中写道:这个确切的地址似乎不起作用,仍然http://www.skbuff.net/iputils提供了其他链接,包括SourceForge 的链接。我已经下载了 iputils-s20151218并阅读了代码。
-n
处理ping_common.c
:那么选项 (
options & F_NUMERIC
) 在以下方面很重要ping.c
:要到达
gethostbyaddr
,两者exiting
和都options & F_NUMERIC
必须为假(因为a || b
不会评估b
是否a
为真)。后者取决于是否-n
使用过。gethostbyaddr
是“尝试查找主机地址的符号名称”。见man 3 gethostbyaddr
。getent hosts
这与您提供 IP 地址时使用的库调用相同(请参阅 参考资料man 1 getent
)。看到不同:
似乎
ping
不-n
只是使用用户提供的字符串;但不是:这里
poczta.wp.pl
被解析为193.17.41.99
,然后193.17.41.99
被解析为poczta.o2.pl
(注意o2
而不是wp
)。的使用-n
会抑制后一步。对于某些地址,会发生这种情况:
但是,如果我提供一个数字地址,那么就没有区别:
这是因为这个片段来自
ping.c
:inet_aton
从 IPv4 数字和点符号转换为二进制形式。它返回1
成功。如果给定的最后一个参数ping
可以转换,则该片段的评估options |= F_NUMERIC
就像-n
was used一样。我实际上是
ping
从源代码编译的两个版本:原始版本和if … options |= F_NUMERIC;
注释掉的版本。修改后的版本行为如下:现在我可以明确回答这个问题了:
不,IPv4 数字和点符号中的地址
ping
(iputils
在 Linux 上)就像-n
使用过的一样工作。我用一对 veth 创建了一个单独的网络命名空间(以确保尽可能少的流量干扰),然后在
wireshark
那里使用。(如果您想复制我的结果并需要该过程的帮助,请参阅此答案,示例 2)。与原件
ping
:ping -n -c 1 8.8.8.8
生成ICMP echo request
和接收ICMP echo reply
. 不涉及 DNS。ping -c 1 8.8.8.8
做同样的事情(这并不奇怪,上面解释过)。这意味着没有 DNS 查找。以下是一些比较测试。
随着我的修改
ping
:ping -n -c 1 8.8.8.8
表现得像原来的。ping -c 1 8.8.8.8
在 ICMP 之后查询 DNS 服务器并收到响应。这是要搞定的dns.google
。再次与原始
ping
:ping -n -c 1 dns.google
查询 DNS 服务器并在 ICMP 之前收到响应。这是翻译dns.google
成8.8.8.8
or8.8.4.4
。ping -c 1 dns.google
查询 DNS 服务器并在 ICMP(转换为8.8.8.8
或转换为)之前8.8.4.4
和 ICMP(转换回)之后分别接收响应。从手册页:
所以区别在于输出: