如何找到我可以发送且不分片的最大 UDP 数据包?

发布于 2024-07-21 19:47:50 字数 259 浏览 16 评论 0原文

我需要知道可以发送到另一台计算机的最大 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

七堇年 2024-07-28 19:47:51

以下是我编写的一些用于检查路径 MTU 问题的 Windows PowerShell。 (一般技术在其他编程语言中实现起来并不太难。)许多防火墙和路由器被不了解的人配置为丢弃所有 ICMP。 路径 MTU 发现取决于是否能够接收设置了需要分段的 ICMP 目标不可达消息,以响应发送设置了不分段的数据包。 使用 GRE 和 IPsec 解决 IPv4 碎片、MTU、MSS 和 PMTUD 问题实际上很好地解释了发现的工作原理。

function Test-IPAddressOrName($ipAddressOrName)
{
    $ipaddress = $null
    $isValidIPAddressOrName = [ipaddress]::TryParse($ipAddressOrName, [ref] $ipaddress)

    if ($isValidIPAddressOrName -eq $false)
    {
        $hasResolveDnsCommand = $null -ne (Get-Command Resolve-DnsName -ErrorAction SilentlyContinue)
        if ($hasResolveDnsCommand -eq $true)
        {
            $dnsResult = Resolve-DnsName -DnsOnly -Name $ipAddressOrName -ErrorAction SilentlyContinue
            $isValidIPAddressOrName = $null -ne $dnsResult
        }
    }

    return $isValidIPAddressOrName
}

function Get-NameAndIPAddress($ipAddressOrName)
{
    $hasResolveDnsCommand = $null -ne (Get-Command Resolve-DnsName -ErrorAction SilentlyContinue)

    $ipAddress = $null
    $validIPAddress = [ipaddress]::TryParse($ipAddressOrName, [ref] $ipAddress)
    $nameAndIp = [PSCustomObject] @{ 'Name' = $null; 'IPAddress' = $null }

    if ($validIPAddress -eq $false)
    {
        if ($hasResolveDnsCommand -eq $true)
        {
            $dnsResult = Resolve-DnsName -DnsOnly $ipAddressOrName -Type A -ErrorAction SilentlyContinue

            if ($null -ne $dnsResult -and $dnsResult.QueryType -eq 'A')
            {
                $nameAndIp.Name = $dnsResult.Name
                $nameAndIp.IPAddress = $dnsResult.IPAddress
            }
            else
            {
                Write-Error "The name $($ipAddressOrName) could not be resolved."
                $nameAndIp = $null
            }
        }
        else
        {
            Write-Warning "Resolve-DnsName not present. DNS resolution check skipped."
        }
    }
    else
    {
        $nameAndIp.IPAddress = $ipAddress

        if ($hasResolveDnsCommand -eq $true)
        {
            $dnsResult = Resolve-DnsName -DnsOnly $ipAddress -Type PTR -ErrorAction SilentlyContinue

            if ($null -ne $dnsResult -and $dnsResult.QueryType -eq 'PTR')
            {
                $nameAndIp.Name = $dnsResult.NameHost
            }
        }
    }

    return $nameAndIp
}

<#
    .Synopsis
    Performs a series of pings (ICMP echo requests) with Don't Fragment specified to discover the path MTU (Maximum Transmission Unit).

    .Description
    Performs a series of pings with Don't Fragment specified to discover the path MTU (Maximum Transmission Unit). An ICMP echo request 
    is sent with a random payload with a payload length specified by the PayloadBytesMinimun. ICMP echo requests of increasing size are 
    sent until a ping response status other than Success is received. If the response status is PackeTooBig, the last successful packet 
    length is returned as a reliable MTU; otherwise, if the respone status is TimedOut, the same size packet is retried up to the number 
    of retries specified. If all of the retries have been exhausted with a response status of TimedOut, the last successful packet 
    length is returned as the assumed MTU.

    .Parameter UseDefaultGateway
    If UseDefaultGateway is specified the default gateway reported by the network interface is used as the destination host.

    .Parameter DestinationHost
    The IP Address or valid fully qualified DNS name of the destination host.

    .Parameter InitialTimeout
    The number of milliseconds to wait for an ICMP echo reply. Internally, this is doubled each time a retry occurs.

    .Parameter Retries
    The number of times to try the ping in the event that no reply is recieved before the timeout.

    .Parameter PayloadBytesMinimum
    The minimum number of bytes in the payload to use. The minimum MTU for IPv4 is 68 bytes; however, in practice, it's extremely rare 
    to see an MTU size less than 576 bytes so the default value is 548 bytes (576 bytes total packet size minus an ICMP header of 28 
    bytes).

    .Parameter PayloadBytesMaximum
    The maximum number of bytes in the payload to use. An IPv4 MTU for jumbo frames is 9000 bytes. The default value is 8973 bytes (9001 
    bytes total packet size, which is 1 byte larger than the maximum IPv4 MTU for a jumbo frame, minus an ICMP header of 28 bytes).

    .Example
    Discover-PathMTU -UseDefaultGateway

    .Example
    Discover-PathMTU -DestinationHost '192.168.1.1'

    .Example
    Discover-PathMTU -DestinationHost 'www.google.com'
#>
function Discover-PathMtu
{
    [CmdletBinding(SupportsShouldProcess = $false)]
    param
    (
        [Parameter(Mandatory = $true, ParameterSetName = 'DefaultGateway')]
        [switch] $UseDefaultGateway,

        [Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true, ParameterSetName = 'IPAddressOrName')]
        [ValidateScript({ Test-IPAddressOrName $_ })]
        [string] $DestinationHost,

        [Parameter(ParameterSetName = 'IPAddressOrName')]
        [Parameter(ParameterSetName = 'DefaultGateway')]
        [int] $InitialTimeout = 3000,

        [Parameter(ParameterSetName = 'IPAddressOrName')]
        [Parameter(ParameterSetName = 'DefaultGateway')]
        [int] $Retries = 3,

        [Parameter(ParameterSetName = 'IPAddressOrName')]
        [Parameter(ParameterSetName = 'DefaultGateway')]
        $PayloadBytesMinimum = 548,

        [Parameter(ParameterSetName = 'IPAddressOrName')]
        [Parameter(ParameterSetName = 'DefaultGateway')]
        $PayloadBytesMaximum = 8973
    )

    begin
    {
        $ipConfiguration = Get-NetIPConfiguration -Detailed | ?{ $_.NetProfile.Ipv4Connectivity -eq 'Internet' -and $_.NetAdapter.Status -eq 'Up' } | Sort { $_.IPv4DefaultGateway.InterfaceMetric } | Select -First 1
        $gatewayIPAddress = $ipConfiguration.IPv4DefaultGateway.NextHop

        $pingOptions = New-Object System.Net.NetworkInformation.PingOptions
        $pingOptions.DontFragment = $true
        $pinger = New-Object System.Net.NetworkInformation.Ping

        $rng = New-Object System.Security.Cryptography.RNGCryptoServiceProvider
    }

    process
    {
        $pingIpAddress = $null

        if ($UseDefaultGateway -eq $true)
        {
            $DestinationHost = $gatewayIPAddress
        }

        $nameAndIP = Get-NameAndIPAddress $DestinationHost

        if ($null -ne $nameAndIP)
        {
            Write-Host "Performing Path MTU discovery for $($nameAndIP.Name) $($nameAndIP.IPAddress)..."

            $pingReply = $null
            $payloadLength = $PayloadBytesMinimum
            $workingPingTimeout = $InitialTimeout

            do
            {
                $payloadLength++

                # Use a random payload to prevent compression in the path from potentially causing a false MTU report.
                [byte[]] $payloadBuffer = (,0x00 * $payloadLength)
                $rng.GetBytes($payloadBuffer)

                $pingCount = 1

                do
                {
                    $pingReply = $pinger.Send($nameAndIP.IPAddress, $workingPingTimeout, $payloadBuffer, $pingOptions)

                    if ($pingReply.Status -notin 'Success', 'PacketTooBig', 'TimedOut')
                    {
                        Write-Warning "An unexpected ping reply status, $($pingReply.Status), was received in $($pingReply.RoundtripTime) milliseconds on attempt $($pingCount)."
                    }
                    elseif ($pingReply.Status -eq 'TimedOut')
                    {
                        Write-Warning "The ping request timed out while testing a packet of size $($payloadLength + 28) using a timeout value of $($workingPingTimeout) milliseconds on attempt $($pingCount)."
                        $workingPingTimeout = $workingPingTimeout * 2
                    }
                    else
                    {
                        Write-Verbose "Testing packet of size $($payloadLength + 28). The reply was $($pingReply.Status) and was received in $($pingReply.RoundtripTime) milliseconds on attempt $($pingCount)."
                        $workingPingTimeout = $InitialTimeout
                    }

                    Sleep -Milliseconds 10

                    $pingCount++
                } while ($pingReply.Status -eq 'TimedOut' -and $pingCount -le $Retries)
            } while ($payloadLength -lt $PayloadBytesMaximum -and $pingReply -ne $null -and $pingReply.Status -eq 'Success')

            if ($pingReply.Status -eq 'PacketTooBig')
            {
                Write-Host "Reported IPv4 MTU is $($ipConfiguration.NetIPv4Interface.NlMtu). The discovered IPv4 MTU is $($payloadLength + 27)."
            }
            elseif ($pingReply.Status -eq 'TimedOut')
            {
                Write-Host "Reported IPv4 MTU is $($ipConfiguration.NetIPv4Interface.NlMtu). The discovered IPv4 MTU is $($payloadLength + 27), but may not be reliable because the packet appears to have been discarded."    
            }
            else
            {
                Write-Host "Reported IPv4 MTU is $($ipConfiguration.NetIPv4Interface.NlMtu). The discovered IPv4 MTU is $($payloadLength + 27), but may not be reliable, due to an unexpected ping reply status."    
            }

            return $payloadLength + 27
        }
        else
        {
            Write-Error "The name $($DestinationHost) could not be resolved. No Path MTU discovery will be performed."
        }
    }

    end
    {
        if ($null -ne $pinger)
        {
            $pinger.Dispose()
        }

        if ($null -ne $rng)
        {
            $rng.Dispose()
        }
    }
}

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.

function Test-IPAddressOrName($ipAddressOrName)
{
    $ipaddress = $null
    $isValidIPAddressOrName = [ipaddress]::TryParse($ipAddressOrName, [ref] $ipaddress)

    if ($isValidIPAddressOrName -eq $false)
    {
        $hasResolveDnsCommand = $null -ne (Get-Command Resolve-DnsName -ErrorAction SilentlyContinue)
        if ($hasResolveDnsCommand -eq $true)
        {
            $dnsResult = Resolve-DnsName -DnsOnly -Name $ipAddressOrName -ErrorAction SilentlyContinue
            $isValidIPAddressOrName = $null -ne $dnsResult
        }
    }

    return $isValidIPAddressOrName
}

function Get-NameAndIPAddress($ipAddressOrName)
{
    $hasResolveDnsCommand = $null -ne (Get-Command Resolve-DnsName -ErrorAction SilentlyContinue)

    $ipAddress = $null
    $validIPAddress = [ipaddress]::TryParse($ipAddressOrName, [ref] $ipAddress)
    $nameAndIp = [PSCustomObject] @{ 'Name' = $null; 'IPAddress' = $null }

    if ($validIPAddress -eq $false)
    {
        if ($hasResolveDnsCommand -eq $true)
        {
            $dnsResult = Resolve-DnsName -DnsOnly $ipAddressOrName -Type A -ErrorAction SilentlyContinue

            if ($null -ne $dnsResult -and $dnsResult.QueryType -eq 'A')
            {
                $nameAndIp.Name = $dnsResult.Name
                $nameAndIp.IPAddress = $dnsResult.IPAddress
            }
            else
            {
                Write-Error "The name $($ipAddressOrName) could not be resolved."
                $nameAndIp = $null
            }
        }
        else
        {
            Write-Warning "Resolve-DnsName not present. DNS resolution check skipped."
        }
    }
    else
    {
        $nameAndIp.IPAddress = $ipAddress

        if ($hasResolveDnsCommand -eq $true)
        {
            $dnsResult = Resolve-DnsName -DnsOnly $ipAddress -Type PTR -ErrorAction SilentlyContinue

            if ($null -ne $dnsResult -and $dnsResult.QueryType -eq 'PTR')
            {
                $nameAndIp.Name = $dnsResult.NameHost
            }
        }
    }

    return $nameAndIp
}

<#
    .Synopsis
    Performs a series of pings (ICMP echo requests) with Don't Fragment specified to discover the path MTU (Maximum Transmission Unit).

    .Description
    Performs a series of pings with Don't Fragment specified to discover the path MTU (Maximum Transmission Unit). An ICMP echo request 
    is sent with a random payload with a payload length specified by the PayloadBytesMinimun. ICMP echo requests of increasing size are 
    sent until a ping response status other than Success is received. If the response status is PackeTooBig, the last successful packet 
    length is returned as a reliable MTU; otherwise, if the respone status is TimedOut, the same size packet is retried up to the number 
    of retries specified. If all of the retries have been exhausted with a response status of TimedOut, the last successful packet 
    length is returned as the assumed MTU.

    .Parameter UseDefaultGateway
    If UseDefaultGateway is specified the default gateway reported by the network interface is used as the destination host.

    .Parameter DestinationHost
    The IP Address or valid fully qualified DNS name of the destination host.

    .Parameter InitialTimeout
    The number of milliseconds to wait for an ICMP echo reply. Internally, this is doubled each time a retry occurs.

    .Parameter Retries
    The number of times to try the ping in the event that no reply is recieved before the timeout.

    .Parameter PayloadBytesMinimum
    The minimum number of bytes in the payload to use. The minimum MTU for IPv4 is 68 bytes; however, in practice, it's extremely rare 
    to see an MTU size less than 576 bytes so the default value is 548 bytes (576 bytes total packet size minus an ICMP header of 28 
    bytes).

    .Parameter PayloadBytesMaximum
    The maximum number of bytes in the payload to use. An IPv4 MTU for jumbo frames is 9000 bytes. The default value is 8973 bytes (9001 
    bytes total packet size, which is 1 byte larger than the maximum IPv4 MTU for a jumbo frame, minus an ICMP header of 28 bytes).

    .Example
    Discover-PathMTU -UseDefaultGateway

    .Example
    Discover-PathMTU -DestinationHost '192.168.1.1'

    .Example
    Discover-PathMTU -DestinationHost 'www.google.com'
#>
function Discover-PathMtu
{
    [CmdletBinding(SupportsShouldProcess = $false)]
    param
    (
        [Parameter(Mandatory = $true, ParameterSetName = 'DefaultGateway')]
        [switch] $UseDefaultGateway,

        [Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true, ParameterSetName = 'IPAddressOrName')]
        [ValidateScript({ Test-IPAddressOrName $_ })]
        [string] $DestinationHost,

        [Parameter(ParameterSetName = 'IPAddressOrName')]
        [Parameter(ParameterSetName = 'DefaultGateway')]
        [int] $InitialTimeout = 3000,

        [Parameter(ParameterSetName = 'IPAddressOrName')]
        [Parameter(ParameterSetName = 'DefaultGateway')]
        [int] $Retries = 3,

        [Parameter(ParameterSetName = 'IPAddressOrName')]
        [Parameter(ParameterSetName = 'DefaultGateway')]
        $PayloadBytesMinimum = 548,

        [Parameter(ParameterSetName = 'IPAddressOrName')]
        [Parameter(ParameterSetName = 'DefaultGateway')]
        $PayloadBytesMaximum = 8973
    )

    begin
    {
        $ipConfiguration = Get-NetIPConfiguration -Detailed | ?{ $_.NetProfile.Ipv4Connectivity -eq 'Internet' -and $_.NetAdapter.Status -eq 'Up' } | Sort { $_.IPv4DefaultGateway.InterfaceMetric } | Select -First 1
        $gatewayIPAddress = $ipConfiguration.IPv4DefaultGateway.NextHop

        $pingOptions = New-Object System.Net.NetworkInformation.PingOptions
        $pingOptions.DontFragment = $true
        $pinger = New-Object System.Net.NetworkInformation.Ping

        $rng = New-Object System.Security.Cryptography.RNGCryptoServiceProvider
    }

    process
    {
        $pingIpAddress = $null

        if ($UseDefaultGateway -eq $true)
        {
            $DestinationHost = $gatewayIPAddress
        }

        $nameAndIP = Get-NameAndIPAddress $DestinationHost

        if ($null -ne $nameAndIP)
        {
            Write-Host "Performing Path MTU discovery for $($nameAndIP.Name) $($nameAndIP.IPAddress)..."

            $pingReply = $null
            $payloadLength = $PayloadBytesMinimum
            $workingPingTimeout = $InitialTimeout

            do
            {
                $payloadLength++

                # Use a random payload to prevent compression in the path from potentially causing a false MTU report.
                [byte[]] $payloadBuffer = (,0x00 * $payloadLength)
                $rng.GetBytes($payloadBuffer)

                $pingCount = 1

                do
                {
                    $pingReply = $pinger.Send($nameAndIP.IPAddress, $workingPingTimeout, $payloadBuffer, $pingOptions)

                    if ($pingReply.Status -notin 'Success', 'PacketTooBig', 'TimedOut')
                    {
                        Write-Warning "An unexpected ping reply status, $($pingReply.Status), was received in $($pingReply.RoundtripTime) milliseconds on attempt $($pingCount)."
                    }
                    elseif ($pingReply.Status -eq 'TimedOut')
                    {
                        Write-Warning "The ping request timed out while testing a packet of size $($payloadLength + 28) using a timeout value of $($workingPingTimeout) milliseconds on attempt $($pingCount)."
                        $workingPingTimeout = $workingPingTimeout * 2
                    }
                    else
                    {
                        Write-Verbose "Testing packet of size $($payloadLength + 28). The reply was $($pingReply.Status) and was received in $($pingReply.RoundtripTime) milliseconds on attempt $($pingCount)."
                        $workingPingTimeout = $InitialTimeout
                    }

                    Sleep -Milliseconds 10

                    $pingCount++
                } while ($pingReply.Status -eq 'TimedOut' -and $pingCount -le $Retries)
            } while ($payloadLength -lt $PayloadBytesMaximum -and $pingReply -ne $null -and $pingReply.Status -eq 'Success')

            if ($pingReply.Status -eq 'PacketTooBig')
            {
                Write-Host "Reported IPv4 MTU is $($ipConfiguration.NetIPv4Interface.NlMtu). The discovered IPv4 MTU is $($payloadLength + 27)."
            }
            elseif ($pingReply.Status -eq 'TimedOut')
            {
                Write-Host "Reported IPv4 MTU is $($ipConfiguration.NetIPv4Interface.NlMtu). The discovered IPv4 MTU is $($payloadLength + 27), but may not be reliable because the packet appears to have been discarded."    
            }
            else
            {
                Write-Host "Reported IPv4 MTU is $($ipConfiguration.NetIPv4Interface.NlMtu). The discovered IPv4 MTU is $($payloadLength + 27), but may not be reliable, due to an unexpected ping reply status."    
            }

            return $payloadLength + 27
        }
        else
        {
            Write-Error "The name $($DestinationHost) could not be resolved. No Path MTU discovery will be performed."
        }
    }

    end
    {
        if ($null -ne $pinger)
        {
            $pinger.Dispose()
        }

        if ($null -ne $rng)
        {
            $rng.Dispose()
        }
    }
}
邮友 2024-07-28 19:47:51

对于 UDP 应用程序,如果您想避免 IP 碎片或丢弃数据包,则必须自行处理端到端 MTU。 对于任何应用程序,建议的方法是尽最大努力使用 PMTU 来选择最大数据报,或发送 << 最大数据报。 最小 PMTU

https://www.rfc-editor.org/rfc/rfc5405#第3.2节

应用程序设计者的单播 UDP 使用指南“不应发送超过 PMTU 的数据报,应发现 PMTU 或发送 < 最小 PMTU 的数据报

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

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

和影子一齐双人舞 2024-07-28 19:47:50

以下内容并没有直接回答您的问题,但您可能会觉得很有趣; 它表示 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].

尹雨沫 2024-07-28 19:47:50

您自己的 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.

残花月 2024-07-28 19:47:50

除了之前的所有答案之外,引用经典

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.

花间憩 2024-07-28 19:47:50

这对我来说是一个有趣的话题。 当通过 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文