How to find the largest UDP packet I can send with

2019-01-12 18:28发布

问题:

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?

回答1:

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:

  • Re: UDP fragmentation says you should use ICMP instead of UDP to discover MTU
  • Path MTU Discovery says that a TCP connection might include implicit MTU negotiation via ICMP

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].



回答2:

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.



回答3:

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.



回答4:

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.



回答5:

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://tools.ietf.org/html/rfc5405#section-3.2

Unicast UDP Usage Guidelines for Application Designers "SHOULD NOT send datagrams that exceed the PMTU, SHOULD discover PMTU or send datagrams < minimum PMTU

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://docs.microsoft.com/en-us/windows/desktop/winsock/ipproto-ip-socket-options