Как найти самый большой пакет UDP, который я могу отправить без фрагментации?

Самый простой способ, который я нашел для запуска задачи синхронно и без блокировки потока пользовательского интерфейса, - использовать RunSynchronously () как:

Task t = new Task(() => 
{ 
   //.... YOUR CODE ....
});
t.RunSynchronously();

В моем случае у меня есть событие, которое срабатывает, когда что-то происходит. Я не знаю, сколько раз это произойдет. Таким образом, я использую код выше в моем случае, поэтому всякий раз, когда он срабатывает, он создает задачу. Задачи выполняются синхронно, и это отлично работает для меня. Я был просто удивлен, что мне потребовалось столько времени, чтобы выяснить, насколько это просто. Обычно рекомендации намного сложнее и подвержены ошибкам. Это было просто и чисто.

54
задан Unknown 23 May 2009 в 03:13
поделиться

4 ответа

Нижеследующее не дает прямого ответа на ваш вопрос, но может показаться вам интересным; в нем говорится, что IP-пакеты могут быть разобраны / повторно собраны и, следовательно, превышают ограничение на нижележащий носитель (например, 1500-байтный Ethernet): Устранение проблем IP-фрагментации, MTU, MSS и PMTUD с помощью GRE и IPSEC


Подробнее по этой теме:

  • Re: фрагментация UDP говорит, что вы должны использовать ICMP вместо UDP для обнаружения MTU
  • Path MTU Discovery говорит, что TCP-соединение может включать неявное согласование MTU через ICMP

I не знаю о генерации ICMP через API в Windows: одно время такой API предлагался, и был спорным, потому что люди утверждали, что это упростит написание программного обеспечения, реализующего функцию отказа в обслуживании путем создания потока сообщений ICMP.

Нет, похоже, что это реализовано: см. пример Winsock Programmer's FAQ Примеры: Ping: метод сырых сокетов .

Итак, чтобы определить MTU, сгенерируйте пакеты ping с флагом «не фрагментировать».

Может быть, есть более простой API, чем этот, Я не знаю; но я надеюсь, что я дал вам понять лежащие в основе протоколы.

Итак, чтобы обнаружить MTU, сгенерируйте пакеты ping с флагом «не фрагментировать».

Может быть, есть более простой API, чем этот, я не знаю; но я надеюсь, что я дал вам понять лежащие в основе протоколы.

Итак, чтобы обнаружить MTU, сгенерируйте пакеты ping с флагом «не фрагментировать».

Может быть, есть более простой API, чем этот, я не знаю; но я надеюсь, что я дал вам понять лежащие в основе протоколы.

24
ответ дан 7 November 2019 в 08:11
поделиться

Вот немного Windows PowerShell, который я записал для проверки на проблемы MTU Пути. (Общая техника не слишком трудна для реализации на других языках программирования.) Много брандмауэров и маршрутизаторов настроено для отбрасывания всего ICMP людьми, которые не знают ничего лучшего. Открытие MTU пути зависит от способности принять Место назначения ICMP Недостижимое сообщение с Fragementation, Необходимый набор в ответ на отправку пакета с не Фрагментирует набор. Фрагментация IPv4 Твердости, MTU, MSS и Проблемы PMTUD с GRE и IPsec на самом деле делают действительно хорошее задание объяснения, как открытие работает.

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 

Вот немного Windows PowerShell, который я записал для проверки на проблемы MTU Пути. (Общая техника не слишком трудна для реализации на других языках программирования.) Много брандмауэров и маршрутизаторов настроено для отбрасывания всего ICMP людьми, которые не знают ничего лучшего. Открытие MTU пути зависит от способности принять Место назначения ICMP Недостижимое сообщение с Fragementation, Необходимый набор в ответ на отправку пакета с не Фрагментирует набор. Фрагментация IPv4 Твердости, MTU, MSS и Проблемы PMTUD с GRE и IPsec на самом деле делают действительно хорошее задание объяснения, как открытие работает.

[110] })] [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 | ?{

Вот немного Windows PowerShell, который я записал для проверки на проблемы MTU Пути. (Общая техника не слишком трудна для реализации на других языках программирования.) Много брандмауэров и маршрутизаторов настроено для отбрасывания всего ICMP людьми, которые не знают ничего лучшего. Открытие MTU пути зависит от способности принять Место назначения ICMP Недостижимое сообщение с Fragementation, Необходимый набор в ответ на отправку пакета с не Фрагментирует набор. Фрагментация IPv4 Твердости, MTU, MSS и Проблемы PMTUD с GRE и IPsec на самом деле делают действительно хорошее задание объяснения, как открытие работает.

[110].NetProfile.Ipv4Connectivity -eq 'Internet' -and

Вот немного Windows PowerShell, который я записал для проверки на проблемы MTU Пути. (Общая техника не слишком трудна для реализации на других языках программирования.) Много брандмауэров и маршрутизаторов настроено для отбрасывания всего ICMP людьми, которые не знают ничего лучшего. Открытие MTU пути зависит от способности принять Место назначения ICMP Недостижимое сообщение с Fragementation, Необходимый набор в ответ на отправку пакета с не Фрагментирует набор. Фрагментация IPv4 Твердости, MTU, MSS и Проблемы PMTUD с GRE и IPsec на самом деле делают действительно хорошее задание объяснения, как открытие работает.

[110].NetAdapter.Status -eq 'Up' } | Sort {

Вот немного Windows PowerShell, который я записал для проверки на проблемы MTU Пути. (Общая техника не слишком трудна для реализации на других языках программирования.) Много брандмауэров и маршрутизаторов настроено для отбрасывания всего ICMP людьми, которые не знают ничего лучшего. Открытие MTU пути зависит от способности принять Место назначения ICMP Недостижимое сообщение с Fragementation, Необходимый набор в ответ на отправку пакета с не Фрагментирует набор. Фрагментация IPv4 Твердости, MTU, MSS и Проблемы PMTUD с GRE и IPsec на самом деле делают действительно хорошее задание объяснения, как открытие работает.

[110].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() } } }
0
ответ дан 7 November 2019 в 08:11
поделиться

Ваш собственный MTU доступен в реестре , но на практике MTU соответствует наименьшему MTU в пути между вашей машиной и местом назначения. Его обе переменные и могут быть определены только эмпирически. Существует ряд RFC , показывающих, как это определить.

Локальные сети могут иметь очень большие значения MTU, поскольку сетевое оборудование обычно однородно или, по крайней мере, управляется централизованно.

2
ответ дан 7 November 2019 в 08:11
поделиться

В дополнение ко всем предыдущим ответам, цитируя классический :

IPv4 и IPv6 определяют минимальный размер буфера повторной сборки , минимальный размер дейтаграммы, который, как мы гарантируем, должна поддерживать любая реализация. Для IPv4 это 576 байт. IPv6 увеличивает это значение до 1280 байт.


Это в значительной степени означает, что вы хотите ограничить размер дейтаграммы до 576, если вы работаете через общедоступный Интернет и контролируете только одну сторону обмена - это то, что делает большинство стандартных протоколов на основе UDP.

Также обратите внимание, что PMTU - это динамическое свойство пути. Это одна из тех вещей, которыми TCP занимается за вас. Если вы не готовы повторно реализовать множество логических схем последовательности, синхронизации и повторной передачи, используйте TCP для любой критически важной сети. Бенчмарк, тест, профиль, то есть докажите , что TCP является вашим узким местом, только тогда рассмотрите UDP.

13
ответ дан 7 November 2019 в 08:11
поделиться