如何找到我可以发送且不分片的最大 UDP 数据包?
我需要知道可以发送到另一台计算机的最大 UDP 数据包(不带碎片)是多少。
该大小通常称为 MTU(最大传输单元)。 假设两台计算机之间有许多可能具有不同 MTU 的路由器和调制解调器。
我读到 Windows 中的 TCP 实现会自动查找路径中的最大 MTU。
我也在试验,发现从我的电脑到服务器的最大MTU是57712字节+标头。 任何高于此的东西都被丢弃。 我的计算机在 LAN 上,MTU 不是应该在 1500 字节左右吗?
I need to know what the largest UDP packet I can send to another computer is without fragmentation.
This size is commonly known as the MTU (Maximum Transmission Unit). Supposedly, between 2 computers, will be many routers and modems that may have different MTUs.
I read that the TCP implementation in windows automatically finds the maximum MTU in a path.
I was also experimenting, and I found out that the maximum MTU from my computer to a server was 57712 bytes+header. Anything above that was discarded. My computer is on a LAN, isn't the MTU supposed to be around 1500 bytes?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
以下是我编写的一些用于检查路径 MTU 问题的 Windows PowerShell。 (一般技术在其他编程语言中实现起来并不太难。)许多防火墙和路由器被不了解的人配置为丢弃所有 ICMP。 路径 MTU 发现取决于是否能够接收设置了需要分段的 ICMP 目标不可达消息,以响应发送设置了不分段的数据包。 使用 GRE 和 IPsec 解决 IPv4 碎片、MTU、MSS 和 PMTUD 问题实际上很好地解释了发现的工作原理。
Here's a bit of Windows PowerShell that I wrote to check for Path MTU issues. (The general technique is not too hard to implement in other programming languages.) A lot of firewalls and routers are configured to drop all ICMP by people who don't know any better. Path MTU Discovery depends on being able to receive an ICMP Destination Unreachable message with Fragementation Needed set in response to sending a packet with Don't Fragment set. The Resolve IPv4 Fragmentation, MTU, MSS, and PMTUD Issues with GRE and IPsec actually does a really good job of explaining how discovery works.
对于 UDP 应用程序,如果您想避免 IP 碎片或丢弃数据包,则必须自行处理端到端 MTU。 对于任何应用程序,建议的方法是尽最大努力使用 PMTU 来选择最大数据报,或发送 << 最大数据报。 最小 PMTU
https://www.rfc-editor.org/rfc/rfc5405#第3.2节
Windows 通过其基本套接字选项界面显示设置和访问 PMTU 信息:
您可以确保 PMTU 发现是通过 IP_MTU_DISCOVER,您可以通过 IP_MTU 读取 MTU
。 noreferrer">https://learn.microsoft.com/en-us/windows/desktop/winsock/ipproto-ip-socket-options
For UDP applications you must handle end-to-end MTU yourself if you want to avoid IP fragmentation or dropped packets. The recommended approach for any application is to do your best to use PMTU to pick your maximum datagram, or send datagrams < minimum PMTU
https://www.rfc-editor.org/rfc/rfc5405#section-3.2
Windows appears to settings and access to PMTU information via it's basic socket options interface:
You can make sure PMTU discover is on via IP_MTU_DISCOVER, and you can read the MTU via IP_MTU.
https://learn.microsoft.com/en-us/windows/desktop/winsock/ipproto-ip-socket-options
以下内容并没有直接回答您的问题,但您可能会觉得很有趣; 它表示 IP 数据包可以被分解/重新组装,因此大于底层介质(例如 1500 字节以太网)的限制:使用 GRE 和 IPSEC 解决 IP 碎片、MTU、MSS 和 PMTUD 问题
有关此主题的更多信息:
我不知道如何通过 ICMP 生成 ICMP Windows 上的 API:曾经提出过这样的 API,但引起了争议,因为人们认为这样可以轻松编写通过生成大量 ICMP 消息来实现拒绝服务功能的软件。
不,它看起来已经实现了:例如参见Winsock程序员的常见问题解答示例: Ping:原始套接字方法。
因此,要发现 MTU,请生成带有“不分段”标志的 ping 数据包。
也许有比这更简单的 API,我不知道; 但我希望我已经让您了解了底层协议。
The following doesn't answer your question directly but you might find it interesting; it says that IP packets can be disassembled/reassembled, and therefore bigger than limit on the underling media (e.g. 1500-byte Ethernet): Resolve IP Fragmentation, MTU, MSS, and PMTUD Issues with GRE and IPSEC
More on this topic:
I don't know about generating ICMP via an API on Windows: at one time such an API was proposed, and was controversial because people argued that would make it easy to write software that implements denial-of-service functionality by generating a flood of ICMP messages.
No, it looks like it is implemented: see for example Winsock Programmer's FAQ Examples: Ping: Raw Sockets Method.
So, to discover MTU, generate ping packets with the 'do not fragment' flag.
Maybe there's an easier API than this, I don't know; but I hope I've given you to understand the underlying protocol[s].
您自己的 MTU 可在 注册表 中找到,但实际的 MTU 是转到您的计算机和目标之间的路径中最小的 MTU。 它既可变又只能凭经验确定。 有许多 RFC 展示了如何确定它。
LAN 内部可以具有非常大的 MTU 值,因为网络硬件通常是同类的或至少是集中管理的。
Your own MTU is available in the registry, but the MTU in practice is going to the smallest MTU in the path between your machine and the destination. Its both variable and can only be determined empirically. There are a number of RFCs showing how to determine it.
LAN's can internally have very large MTU values, since the network hardware is typically homogeneous or at least centrally administrated.
除了之前的所有答案之外,引用经典:
IPv4 and IPv6 define minimum reassembly buffer size, the minimum datagram size that we are guaranteed any implementation must support. For IPv4, this is 576 bytes. IPv6 raises this to 1,280 bytes.
这很漂亮这意味着如果您在公共互联网上工作并且仅控制交换的一侧,那么您希望将数据报大小限制在 576 以下 - 这就是大多数基于 UDP 的标准协议所做的事情。
另请注意,PMTU 是路径的动态属性。 这是 TCP 为您处理的事情之一。 除非您准备好重新实现大量排序、计时和重传逻辑,否则请对任何关键网络使用 TCP。 基准测试、测试、分析,即证明 TCP 是您的瓶颈,然后才考虑UDP。
In addition to all the previous answers, quoting the classic:
IPv4 and IPv6 define minimum reassembly buffer size, the minimum datagram size that we are guaranteed any implementation must support. For IPv4, this is 576 bytes. IPv6 raises this to 1,280 bytes.
This pretty much means that you want to limit your datagram size to under 576 if you work over public internet and you control only one side of the exchange - that's what most of the standard UDP-based protocols do.
Also note that PMTU is a dynamic property of the path. This is one of the things TCP deals with for you. Unless you are ready to re-implement lots of sequencing, timing, and retransmission logic, use TCP for any critical networking. Benchmark, test, profile, i.e. prove that TCP is your bottleneck, only then consider UDP.
这对我来说是一个有趣的话题。 当通过 UDP 在现实世界互联网上传输大块 UDP 数据时,也许一些实际结果可能会令人感兴趣,并且以每秒 1 个数据包的传输速率,数据会继续出现,且数据包丢失最少,最高可达 2K 左右。 在此过程中,您会开始遇到问题,但我们通常会毫无困难地传送 1600 多个字节的数据包 - 这是通过 GPRS 移动网络以及全球广域网进行的。 在大约 1K 时,假设信号稳定(事实并非如此!),您的数据包丢失率较低。
有趣的是,这不是奇怪的数据包,而是通常会持续几秒钟的数据包暴风雨 - 这可能就是 VoIP 呼叫偶尔崩溃的原因。
This is an interesting topic for me. Perhaps some practical results might be of interest when delivering chunky UDP data around the real world internet via UDP, and with a transmission rate of 1 packet a second, data continues to turn up with minimal packet loss up to about 2K. Over this and you start running into issues, but regularly we delivered 1600+ bytes packets without distress - this is over GPRS mobile networks as well as WAN world wide. At ~1K assuming the signal is stable (its not!) you get low packet loss.
Interestingly its not the odd packet, but often a squall of packets for a few seconds - which presumably is why VoIP calls just collapse occasionally.