4

Скажем, у меня есть два разъема, которые связаны друг с другом (Socket A и Socket B).

Если компьютер с Socket B отключен от источника питания, то если Socket A пытается отправить некоторые данные в Socket B , данные не будут подтверждены, и поэтому TCP будет повторно и снова передавать данные в надежде на подтверждение, пока TCP не выдаст и решает больше не передавать данные и сообщает Socket A что произошла ошибка сокета WSAECONNABORTED (10053) .

Мои вопросы:

  • Гарантируется ли, что я всегда получу ошибку сокета WSAECONNABORTED (10053) после некоторых повторных попыток повторной передачи (я верю, что это так, потому что в противном случае TCP просто продолжит повторную передачу навсегда!)?
  • Сколько повторных попыток повторной передачи требуется TCP для принятия решения об отказе и вызывает ошибку сокета WSAECONNABORTED (10053) ?
  • Можно ли настроить количество повторных попыток передачи?

2 ответа2

1

Таймеры Windows для TCP используют единицу времени, называемую тайм-аутом повторной передачи (RTO), которая основана на предполагаемом времени прохождения сигнала в обоих направлениях (или RTT) между отправителем и получателем, а также на дисперсии в этом времени приема- передачи . Поведение этого таймера указано в RFC 6298 . Для получения дополнительной информации см. Статью Wikipedia Transmission Control Protocol .

В Windows это работает следующим образом:

  1. Оценочный RTO впервые установлен
  2. TCP-сообщение отправлено, и мы ожидаем ACK (подтверждение) пакета
  3. Если ACK не прибыл, мы удваиваем время ожидания и возвращаемся к шагу 2
  4. Если ACK получен, вычисляется новое RTO
  5. Если ACK никогда не получен, соединение прерывается с ошибкой WSAECONNABORTED.

Windows использует два параметра реестра для этого протокола, описанные в этой статье Microsoft
Как изменить максимальное время ожидания повторной передачи TCP/IP.

TcpMaxDataRetransmissions

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters

Value Name:  TcpMaxDataRetransmissions
Data Type:   REG_DWORD - Number
Valid Range: 0 - 0xFFFFFFFF
Default:     5

Описание :

Этот параметр контролирует количество раз, когда TCP повторно передает отдельный сегмент данных (сегмент без соединения) перед прерыванием соединения. Время ожидания повторной передачи удваивается с каждой последующей повторной передачей по соединению. Сбрасывается, когда ответы возобновляются. Базовое значение времени ожидания динамически определяется измеренным временем прохождения сигнала в оба конца по соединению.

TCPInitialRtt

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\ID for Adapter

Value Name:  TCPInitialRtt
Data Type:   REG_DWORD
Valid Range: 300-65535 (milliseconds in decimal)
Default:     0xBB8 (3000 milliseconds expressed in hexadecimal)

Описание:

Этот параметр контролирует начальное время ожидания повторной передачи, которое используется TCP при каждом новом подключении. Он применяется к запросу на соединение (SYN) и к первым сегментам данных, отправляемым по каждому соединению. Например, данные значения "5000 десятичных знаков" устанавливают начальное время повторной передачи равным пяти секундам.

ПРИМЕЧАНИЕ. Вы можете увеличить значение только для начального времени ожидания. Уменьшение значения не поддерживается.

Хотя TCPInitialRtt запускается с начальным таймаутом в 3 секунды, он будет сглажен до более приемлемого значения, когда пакеты будут переданы правильно.

Например, как это работает, если мы возьмем значения по умолчанию, равные 3 секундам RTO и 5 повторным попыткам, общее время ожидания будет:

  1. первый тайм-аут: 3 секунды
  2. второй тайм-аут: 6 секунд
  3. третий тайм-аут: 12 секунд
  4. четвертый тайм-аут: 24 секунды
  5. пятый и последний тайм-аут: 48 секунд

Что дает общее время ожидания 93 секунд, прежде чем соединение будет прервано. В большинстве случаев, если соединение когда-либо работало правильно, время ожидания будет намного меньше.

0

Обычно используется время (держать повтор , пока значение тайм - аута не было достигнуто), но это зависит от того, как было написано программное обеспечение клиент / сервер.

Если используется время, то для того, чтобы узнать количество повторных попыток, вам необходимо знать, как часто происходят повторные попытки.

Ниже приведены возможные способы установки таймаута, если программа использует Winsock.

Программное обеспечение также может быть написано для использования числа повторных попыток до сбоя или времени до сбоя, или комбинации обоих.


Source Winsock Программист, часто задаваемые вопросы

2.15 - Как я могу изменить время ожидания для функции Winsock?

Некоторые из блокирующих функций Winsock (например, connect ()) имеют встроенный тайм-аут. Теория, лежащая в основе этого, состоит в том, что только стек имеет всю информацию, необходимую для установки правильного времени ожидания. Тем не менее, некоторые люди считают, что значение, которое использует стек, слишком велико для их приложения; это может быть минутой или дольше.

Вы можете настроить таймауты send () и recv () с помощью параметров setsockopt () SO_SNDTIMEO и SO_RCVTIMEO. ,

Для других функций Winsock лучшим решением является полное отсутствие блокировки сокетов. Все неблокирующие методы сокетов предоставляют способы для создания пользовательских таймаутов:

  • Неблокирующие сокеты с select () - Пятый параметр функции select () является значением времени ожидания.

  • Асинхронные сокеты - используйте Windows API SetTimer ().

  • Объекты событий - WSAWaitForMultipleEvents () имеет параметр времени ожидания.

  • Таймеры ожидания - вызов CreateWaitableTimers () для создания ожидаемого таймера, который затем вы можете передать функции, такой как WSAEventSelect (), вместе с вашими сокетами: если ни один из сокетов не будет сигнализирован до того, как таймер отключится, функция блокировки все равно вернется.

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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .