Я делал некоторые чтения в окно приема TCP (RWIN), максимальный размер сегмента (MSS) и максимальный блок передачи (MTU). У меня сразу несколько вопросов, и мне нужна помощь опытного пользователя!

Следующие вопросы основаны на моем использовании Wireshark с клиентом Win7 для просмотра кадров в потоке TCP:

  1. Где вы смотрите (в потоке TCP), чтобы найти RWIN в использовании? Это SYN, SYN-ACK или ACK? У меня сложилось впечатление, что он находится в пакете SYN трехстороннего рукопожатия.
  2. Что говорит удаленный компьютер: "Значение размера окна" 16425 и "Расчетный размер окна" 65700 (Wireshark устанавливает масштабный коэффициент 4, то есть 16425 * 4 = 65700) в пакете ACK?
  3. Какой компьютер определяет значение RWIN, используемое во время передачи - клиент или удаленный компьютер?
  4. В соответствии с завершением TCP-соединения существует FIN-ACK, который указывает, что удаленный компьютер хочет завершить соединение, за которым следует ACK от клиента и затем RST-ACK снова клиентом, таким образом закрывая соединение. Имеет ли значение RWIN в пакетах FIN-ACK и ACK во время этого процесса завершения какое-либо значение, поскольку они очень отличаются от значений RWIN, указанных в трехстороннем рукопожатии?

У меня есть еще несколько вопросов, но ответ здесь может иметь отношение к ним, поэтому я сначала подожду несколько ответов :)

Благодарю. QF

1 ответ1

2

ОК ... сначала легкие детали.

MTU - это максимальная единица передачи в сетевом соединении. По сути, это указывает, насколько большой пакет может обрабатывать канал локальной сети ... это размер "уровня 2" (обычно Ethernet), поэтому IP, TCP, UDP и другие заголовки засчитываются в это значение. Довольно просто.

MSS - максимальный размер сегмента. Это значение TCP, которое отправляется в пакетах SYN (как SYN, так и SYN/ACK). Он определяет объем данных, которые могут содержаться в сегменте TCP. Это элемент уровня TCP, поэтому, если IP-пакет фрагментируется при передаче, MSS ссылается на объем данных в сегменте TCP повторно собранного пакета. Немного менее простой, но все же довольно легко понять.

Теперь все становится сложным.

RWIN - это окно получения TCP. Это значение, указанное на стороне получателя TCP-соединения в поле "Размер окна" заголовка TCP. Окно постоянно корректирует свой размер во время TCP-соединения. Есть окно для каждого направления TCP-соединения. Конечные точки TCP не будут идеально синхронизированы друг с другом относительно текущего размера окна направления соединения TCP на время соединения TCP.

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

Передающая сторона TCP-соединения не будет передавать больше данных, чем размер окна, пока не получит обратно пакеты подтверждения, которые увеличивают размер окна.


ОК ... немного глубже, здесь ...

Рассмотрим гипотетическую одностороннюю передачу данных с размером буфера в приемнике 10 байтов. В начале соединения размер окна будет 10.

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

Затем отправитель отправляет сегмент с 3 байтами данных. Отправитель считает, что размер окна теперь составляет 2 байта (10 - 5 = 5, 5 - 3 = 2). Получатель до сих пор не получил пакетов, поэтому он считает, что размер окна равен 10. Отправитель теперь держит 8 байтов данных для возможной повторной передачи.

Получатель получает первый сегмент, он сохраняет данные в буфере и отправляет подтверждение. Важно отметить, что ОС получила данные и подтверждает их получение, но приложение все еще не имеет данных. Подтверждение будет иметь ACK 5 (относительно начальных порядковых номеров, которые были выбраны) и размер окна 5 (потому что данные все еще находятся в буфере, принимая 5 байтов 10-байтового буфера).

Отправитель получает подтверждение 5 байтов, поэтому он может бросить первые 5 байтов, которые он держал для повторной передачи, потому что он знает, что они успешно достигли получателя. Это все еще держит на других 3 байтах от второго сегмента, хотя, потому что они еще не были подтверждены. Отправитель видит, что размер окна, отправляемого получателем, равен 5, но это представляет 5 байтов от номера подтверждения. Отправитель знает, что он уже отправил еще 3 байта, для которых он не получил подтверждение, поэтому он все еще думает, что размер окна составляет 2 байта.

Отправитель теперь отправляет сегмент с 2 байтами данных. Теперь он видит нулевое окно TCP, что означает, что он не может отправлять больше данных, пока получатель не откроет окно дальше. Отправитель снова удерживает 5 байтов данных для возможной повторной передачи (3 из второго сегмента и 2 из третьего сегмента).

Получатель получает второй сегмент с 3 байтами в нем. Теперь он имеет 8 байтов данных в своем буфере. Он отправляет пакет подтверждения с номером подтверждения 8 (относительно начального порядкового номера) и размером окна 2. Эти 8 байтов данных все еще находятся в буфере ОС.

Теперь приложение читает 7 байтов данных из буфера. В буфере теперь содержится 1 байт данных. Общий размер окна был 10, но с одним байтом данных в нем, что оставляет 9 байтов доступным, поэтому получатель отправляет пакет с номером подтверждения 8 (потому что новые данные не были получены), но размер окна теперь 9 (против 2 это было ранее). Это способ увеличения окна, чтобы отправитель мог отправлять больше данных.

Отправитель получает ACK из 8 байтов с размером окна 2. Отправитель может выбросить 3 байта данных из 2-го сегмента, но он уже отправил еще 2 байта, а размер окна в этом пакете равен 2, поэтому отправитель по-прежнему видит окно нулевого размера и не может отправлять больше данных. ,

Получатель получает 3-й сегмент с 2 байтами в нем. Помещает 2 байта в буфер, оставляя 7 байтов свободными. Он отправляет пакет с ACK 10 (5 + 3 + 2) и размером окна 7.

Отправитель получает ACK с номером подтверждения 8 и размером окна 9. Он уже отправил всего 10 байт, поэтому он все еще видит два байта в очереди, поэтому он видит размер окна 7 (9 - 2).

У отправителя есть только 5 байтов для отправки. Это полностью соответствует размеру окна, поэтому он отправляет 5 байтов. Теперь он видит размер окна 2, но это не имеет значения, потому что у него больше нет данных для отправки. Теперь он удерживает 7 байтов данных для возможной повторной передачи.

Отправитель получает ACK с номером подтверждения 10 и размером окна 7. Он бросает 2 байта из 3-го сегмента, все еще имеет 5 байтов, которые он удерживает для потенциальной повторной передачи.

Получатель получает 4-й сегмент с 5 байтами данных, добавляет эти данные в свой буфер (не содержащий 8 байтов), отправляет ACK с номером подтверждения 15 и размером окна 2.

Затем приложение считывает 8 байтов, находящихся в буфере, поэтому буфер теперь пуст. Получатель отправляет ACK с номером подтверждения 15 и размером окна обратно на полные 10.

Отправитель получает ACK с номером подтверждения 15 и размером окна 2. Теперь он может выбросить последние данные, которые он держал, для возможной повторной передачи. Он знает, что все его данные дошли до получателя. На самом деле его не волнует размер окна 2, так как у него больше нет данных для отправки.

Отправитель получает последний ACK с номером подтверждения 15 и размером окна 10.


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

Значения RWIN в пакетах с битами FIN должны иметь одинаковое значение. Можете ли вы привести пример того, что вы видите в Wireshark, чтобы мы могли помочь интерпретировать их?

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