【问题标题】:How to set "don't fragment" flag bit for TCP packet in Go?如何在 Go 中为 TCP 数据包设置“不分段”标志位?
【发布时间】:2016-10-12 04:57:32
【问题描述】:

我打算在 Go 中设置“不分段”标志位,与 C 中的 this post 相同。我检查了 constant list 但我没有找到这个选项。那么 Go 中对应的选项是什么?

提前致谢!

【问题讨论】:

  • 也许你需要自己的循环来不允许片段,如github.com/beatgammit/arduino-tcp-server/blob/master/…
  • @VonC 你好,我不完全明白为什么将第一个字节设置为 0x81(如他们的自述文件中所述)可以防止碎片。我的直觉是,这个幻数可以构成一个数据包的字节而无需分片,但实际上数据包仍然可以分片。我是正确的还是我在这里错过了什么?谢谢!!
  • 好问题。我不知道,除了datatracker.ietf.org/doc/rfc6455/?include_text=1 的第 5.7 节有以0x81 开头的单帧示例。
  • @VonC 谢谢!这个例子是有道理的,也许符合我的假设——这样的字节代表未分段的帧。

标签: sockets go tcp


【解决方案1】:

如何在 Go 中为 TCP 数据包设置“不分片”标志位?

首先,您应该知道 TCP 确实不喜欢 IP 片段。大多数(如果不是全部)主要实现通过使用路径 MTU 发现来避免 TCP 段的分段。

TL;DR 是包含 TCP 段的典型 IP 数据包设置了 DF 位。您可以(并且应该)尝试一下。在这里,我正在嗅探我的机器和 stackoverflow.com 之间的几秒钟流量:

% tshark -w /tmp/tcp.pcap tcp and host stackoverflow.com
<wait a few seconds>
% tshark -r /tmp/tcp.pcap -T fields -e ip.flags | sort | uniq -c
    186 0x00000002

0x02 表示设置了 DF 位。我承认在其他捕获中,我曾在没有 DF 位的 IP 数据包中看到偶尔的 TCP 段;我怀疑rfc1191 对此有解释。


现在回到您的问题,我认为设置 DF 位没有可移植的方法,这是一个更普遍的问题(甚至没有 POSIX 可移植的方法)。 golang.org/x/sys 下的相关包中(可能)有一个逃生舱口供您实施。

例如,在支持IP_DONTFRAG 的Unix 上,例如FreeBSD,可以使用unix.SetsockoptInt 并挖掘相关的常量值。

在 Linux 上没有 IP_DONTFRAG,正如您在 the question you linked 中发现的那样。解决方法似乎是使用IP_MTU_DISCOVER,它恰好可以作为a constant in the unix package 使用。您可以使用相同的unix.SetsockoptInt 进行设置。

【讨论】:

    猜你喜欢
    • 2011-03-30
    • 2014-09-15
    • 2018-02-07
    • 1970-01-01
    • 2023-03-26
    • 1970-01-01
    • 2010-11-01
    • 1970-01-01
    • 2018-11-19
    相关资源
    最近更新 更多