TCP отправляет SYN / ACK для каждого пакета или только для первого соединения? - PullRequest
40 голосов
/ 31 августа 2010

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

<client connect>
SYN
ACK
DATA
DATA
DATA
<client disconnect>

Или он отправляется с каждым пакетом, как этот?

Кроме того, если это первый случай, есть ли какие-либо преимущества UDP над TCP, если вы просто оставляете соединение открытым в течение длительного периода времени?

Ответы [ 3 ]

75 голосов
/ 31 августа 2010

Это вроде как:

+-------------------------------------------------------+
|     client           network            server        |
+-----------------+                +--------------------|
|    (connect)    | ---- SYN ----> |                    |
|                 | <-- SYN,ACK -- |     (accepted)     |
|   (connected)   | ---- ACK ----> |                    |
\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/

when client sends...
\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/
|                 |                |                    |
|     (send)      | ---- data ---> |                    |
|                 | <---- ACK ---- |  (data received)   |
\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/

when server sends...
\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/
|                 |                |                    |
|                 | <--- data ---- |       (send)       |
| (data received) | ---- ACK ----> |                    |
\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/

...and so on, til the connection is shut down or reset

SYN запускает соединение;Вы обычно будете видеть это только когда соединение будет установлено.Но все данные, отправляемые через TCP, требуют ACK.Каждый отправленный байт должен быть учтен, или он будет повторно передан (или сброс соединения (закрыто), в серьезных случаях).

Фактические соединения обычно не точно , как на схеме вышеоднако по двум причинам:

  • ACK могут накапливаться, поэтому один ACK может подтвердить все, полученные до этого момента.Это означает, что вы можете подтвердить две или более отправки одним ACK.
  • ACK - это просто флаг и поле в заголовке TCP.Для посылки требуется полоса пропускания по крайней мере на уровне заголовка, плюс все, что привязано к нижним уровням.Но сегменты данных уже включают все это ... поэтому, если вы отправляете данные, вы можете одновременно отправлять ACK бесплатно.

Большинство стеков TCP / IP пытаются уменьшить количествоголые ACK без чрезмерного риска повторной передачи или сброса соединения.Таким образом, разговор, подобный этому, вполне возможен:

\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/
|                 |                |                    |
|                 | <--- data ---- |       (send)       |
| (data received) |                |                    |
|     (send)      | -- data,ACK -> |                    |
|                 |                |  (data received)   |
|                 | <- data,ACK -- |       (send)       |
| (data received) |                |                    |
|  (wait a bit)   | <--- data ---- |       (send)       |
| (data received) |                |                    |
|     (send)      | -- data,ACK -> |                    |
|                 |                |  (data received)   |
|     (send)      | ---- data ---> |   (wait a bit)     |
|                 |                |  (data received)   |
|                 | <- data,ACK -- |       (send)       |
| (data received) |                |                    |
|  (wait a bit)   |   (dead air)   |                    |
|                 | ---- ACK ----> |                    |
\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/\_/

Что касается UDP, здесь нет встроенной концепции SYN и ACK - UDP по своей природе "ненадежен", а не соединениеориентированы, поэтому понятия не применяются так сильно.Ваше подтверждение обычно будет просто ответом сервера.Но некоторые протоколы прикладного уровня, построенные поверх UDP, будут иметь какой-то специфичный для протокола способ подтверждения отправки и получения данных.

10 голосов
/ 31 августа 2010

SYN только в начале.

ACK находится на последующих сегментах в любом направлении.[править] ACK также определит размер окна.Например, если размер окна равен 100, отправитель может отправить 100 сегментов, прежде чем он ожидает получить ACK.Например, если отправитель отправляет 100 сегментов, но номер сегмента 50 теряется, то получатель получает 1-49 и 51-100.Затем получатель получит подтверждение ACK в течение 50 (следующий ожидаемый сегмент) и установит размер окна равным 1. Отправитель повторно отправит 1 сегмент с порядковым номером 50. Затем получатель подтвердит получение ACK в течение 101 и снова установит размер окна на более высокое число [править]

Оба поля на самом деле являются полями в заголовке TCP и могут быть отправлены с данными, хотя SYN и первый ACK обычно не содержат данных.

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

Конец сеанса также включает в себя рукопожатия с пакетами, помеченными FIN, и относящимися к ним ACK.

Обмененные порядковые номера используются для идентификации потерянных пакетов и включения механизма повторных попыток, а также для повторной сборкивесь поток пакетов в правильном порядке.

Кроме того, если это первый случай, есть ли какие-либо преимущества UDP над TCP, если вы просто оставляете соединение открытым в течение длительного периода времени?

С UDP вы не можете просто держать соединение открытым в течение длительного периода времени.Соединение отсутствует.

Эта последовательность флагов SYN / ACK / FIN устанавливает соединение.

В UDP нет SYN или ACK, поэтому связь является односторонней, доставкане гарантируется и порядок не сохраняется.Но у него меньше накладных расходов, поэтому он полезен, когда скорость важнее надежности, как, например, при потоковой передаче мультимедиа.

Это пока немного упрощено, но это лучшее, что я могу сделать на данный момент.

Об этом гораздо больше в записи в Википедии по TCP и, конечно,в РФЦ.

0 голосов
/ 30 декабря 2017

Представьте это: оригинальный стандарт TCP RFC 793 разрешал отправку данных с первым пакетом SYN.Однако сегодня это не так.То, что вы получаете, это отдельный пакет SYN во время инициации трехстороннего рукопожатия от инициатора запроса соединения.Предположим, A запрашивает соединение с B, поэтому A отправляет пакет с установленным битом SYN.B отвечает ACK для подтверждения получения и отправляет A пакеты ACK + SYN.Данные могут быть переданы отныне.

У Дордала есть очень хорошее объяснение по этому вопросу.Нажмите эту ссылку здесь.

...