Windows 10

Tcp сообщения. Как работает TCP? Схема передачи данных по протоколу TCP-IP

Tcp сообщения. Как работает TCP? Схема передачи данных по протоколу TCP-IP

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

Протокол TCP используется в тех случаях, когда требуется надежная доставка сообщений. Он освобождает прикладные процессы от необходимости использовать таймауты и повторные передачи для обеспечения надежности. Наиболее типичными прикладными процессами, использующими TCP, являются FTP (File Transfer Protocol - протокол передачи файлов) и TELNET. Кроме того, TCP используют система X-Window, rcp (remote copy - удаленное копирование) и другие "r-команды". Большие возможности TCP даются не бесплатно. Реализация TCP требует большой производительности процессора и большой пропускной способности сети. Внутренняя структура модуля TCP гораздо сложнее структуры модуля UDP.

Реализация TCP, как правило, встроена в ядро системы, хотя есть и реализации TCP в контексте приложения.

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

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

Протокол TCP разбивает поток байт на пакеты; он не сохраняет границ между записями. Например, если один прикладной процесс делает 5 записей в TCP-порт, то прикладной процесс на другом конце виртуального канала может выполнить 10 чтений для того, чтобы получить все данные. Но этот же процесс может получить все данные сразу, сделав только одну операцию чтения. Не существует зависимости между числом и размером записываемых сообщений с одной стороны и числом и размером считываемых сообщений с другой стороны.

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

Схема работы пользовательского приложения с TCP в общих чертах состоит в следующем. Для передачи данных пользовательскому процессу надо вызвать соответствующую функцию TCP, с указанием на буфер передаваемых данных. TCP упаковывает эти данные в сегменты своего стека и вызывает функцию передачи протокола нижнего уровня, например IP.

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

Пользовательский интерфейс с TCP может выполнять такие команды как открыть (OPEN) или закрыть соединение (CLOSE), отправить (SEND) или принять (RECEIVE) данные, а также получить состояние соединения (STATUS).

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

В результате работы этого механизма каждый TCP пакет вкладывается в «конверт» протокола нижнего уровня, например, IP. Получившаяся таким образом дейтаграмма содержит в себе TCP-пакет так же как TCP пакет содержит пользовательские данные.

Краткое описание протоколов семейства TCP/IP с расшифровкой аббревиатур

  • ARP (Address Resolution Protocol, протокол определения адресов) : конвертирует 32-разрядные IP-адреса в физические адреса вычислительной сети, например, в 48-разрядные адреса Ethernet.
  • FTP (File Transfer Protocol, протокол передачи файлов) : позволяет передавать файлы с одного компьютера на другой с использованием TCP-соединений. В родственном ему, но менее распространенном протоколе передачи файлов - Trivial File Transfer Protocol (TFTP) - для пересылки файлов применяется UDP, а не TCP.
  • ICMP (Internet Control Message Protocol, протокол управляющих сообщений Internet) : позволяет IP-маршрутизаторам посылать сообщения об ошибках и управляющую информацию другим IP-маршрутизаторам и главным компьютерам сети. ICMP-сообщения "путешествуют" в виде полей данных IP-дейтаграмм и обязательно должны реализовываться во всех вариантах IP.
  • IGMP (Internet Group Management Protocol, протокол управления группами Internet) : позволяет IP-дейтаграммам распространяться в циркулярном режиме (multicast) среди компьютеров, которые принадлежат к соответствующим группам.
  • IP (Internet Protocol, протокол Internet) : низкоуровневый протокол, который направляет пакеты данных по отдельным сетям, связанным вместе с помощью маршрутизаторов для формирования Internet или интрасети. Данные "путешествуют" в форме пакетов, называемых IP-дейтаграммами.
  • SMTP (Simple Mail Transfer Protocol, простой протокол обмена электронной почтой) : определяет формат сообщений, которые SMTP-клиент, работающий на одном компьютере, может использовать для пересылки электронной почты на SMTP-сервер, запущенный на другом компьютере.
  • TCP (Transmission Control Protocol, протокол управления передачей) : протокол ориентирован на работу с подключениями и передает данные в виде потоков байтов. Данные пересылаются пакетами - TCP-сегментами, - которые состоят из заголовков TCP и данных. TCP - "надежный" протокол, потому что в нем используются контрольные суммы для проверки целостности данных и отправка подтверждений, чтобы гарантировать, что переданные данные приняты без искажений.
  • UDP (User Datagram Protocol, протокол пользовательских дейтаграмм) : протокол, не зависящий от подключений, который передает данные пакетами, называемыми UDP-дейтаграммами. UDP - "ненадежный" протокол, поскольку отправитель не получает информацию, показывающую, была ли в действительности принята дейтаграмма.

Состав и предназначение полей заголовка

ТСР-сегменты отправляются как IP-дейтаграммы. Заголовок TCP, следующий за IP-заголовком, содержит информацию TCP-протокола.

Source Port (16 бит). Порт отправителя.

Destination Port (16 бит). Порт получателя.

Sequence Number (32 бита). Номер кадра. Номер кадра первого октета данных в этом сегменте (за исключением пакета, где присутствует флаг SYN). Если в пакете присутствует флаг SYN, то номер данного пакета становится номером начала последовательности (ISN) и номером первого октета данных становится номер ISN+1.

Acknowledgment Number (32 бита). Поле номера кадра подтвержденного получения. Если пакет содержит установленный контрольный бит АСК, то это поле содержит номер следующего пакета данных отправителя, который ожидает получатель. При установленном соединении пакет подтверждения отправляется всегда.

Data Offset (4 бита). Поле величины смещения данных. Оно содержит количество 32-битных слов заголовка TCP-пакета. Это число определяет смещение расположения данных в пакете.

Reserved (6 бит). Резервное поле. Поле зарезервировано.

Флаги управления (слева направо):

  • URG: Флаг срочности
  • АСК: Флаг пакета, содержащего подтверждение получения
  • PSH: Флаг форсированной отправки
  • RST: Переустановка соединения
  • SYN: Синхронизация чисел последовательности
  • FIN: Флаг окончания передачи со стороны отправителя

Window (16 бит). Окно. Это поле содержит количество байт данных, которое отправитель данного сегмента может принять, отсчитанное от номера байта, указанного в поле Acknowledgment Number.

Checksum (16 бит). Поле контрольной суммы. Это поле содержит 16 бит суммы побитных дополнений 16-битных слов заголовка и данных. Если сегмент содержит нечетное число байт заголовка и данных, последний байт дополняется справа нулями. При вычислении контрольной суммы поле контрольной суммы полагается равным нулю.

Urgent Pointer (16 бит). Поле указателя срочных данных. Это поле содержит значение счетчика пакетов, начиная с которого следуют пакеты повышенной срочности. Это поле принимается во внимание только в сегментах с установленным флагом URG.

Options. Поле дополнительных параметров: может быть переменной длины.

Padding. Заполнение: переменная длина. Заполнение (нулями) TCP-заголовка используется для выравнивания его по 32-битному слову.

Эта ссылка на наглядное видео. К сожалению, оно на английском языке, но и так понятно.

Многим знакома аббревиатура TCP, гораздо меньшее количество людей знает, что это протокол передачи данных. Но практически никто не знает, как он устроен.

Внимание! Этот материал рассчитан на тех, кого действительно интересуется вопросом: «Как устроена сеть, и что я могу сделать, если буду это знать». Если же тебя еще смущают слова вроде DNS, Telnet, Socket — то можешь сразу забить на этот материал — такие «страшные» слова тут конечно не встретятся, но от этого содержание понятней не станет…

Для тех кто остался:

Наверное, многие из вас слышали такие слова как SYN-flooding или IP-spoofing. Все это разновидности атак — первая D.O.S., вторая
состоит в подмене IP-адреса. На первый взгляд между этими примерами нет ничего общего, но между тем, это не так — обе эти атаки не возможны без глубокого знания протокола TCP, протокола на котором стоит
Inet.

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

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

Структура TCP-пакета:

Поясню только самые важные места:

Адрес получателя, порт получателя и адрес отправителя, порт отправителя — это надеюсь понятно.

Sequence Number(SYN) — номер очереди или последовательный номер, показывает порядковый номер пакета при передаче, именно поэтому принимающая система собирает пакеты именно так, как надо, а не в том порядке, как они пришли.

Acknowledgment Number(ACK) — номер подтверждения, показывает, на пакет с каким SYN отвечает удаленная система, таким образом мы имеем представление, что удаленная система получила наш пакет с данным
SYN.

Контрольные биты- 6 бит (на схеме между reversed и window). Значения битов:

URG: поле срочного указателя задействовано
ACK: поле подтверждения задействовано
PSH: функция проталкивания
RST: перезагрузка данного соединения
SYN: синхронизация номеров очереди
FIN: нет больше данных для передачи

DATA — это непосредственно те данные, которые мы хотим передать.

Думаю, для начала это все, что нужно, чтобы понять принцип работы протокола. Более подробно о значении остальных полей ты можешь прочитать в в RFC793. Ну а мы лучше разберем как же все-таки это работает на практике.

Когда мы хотим установить соединение, мы отправляем удаленной системе пакет следующей структуры:

Client — SYN (856779) — Host

Где Client- это мы, a Host — это удаленная система. Как ты видишь, мы посылаем пакет лишь с указанием SYN — это значит, что этот пакет первый, мы ни на что не отвечаем (отсутствует ACK). Данный пакет выглядит примерно так:

20 53 52 43 00 00 44 45 53 54 00 00 08 00 45 00 00 2C C3 00 40 00 20 06 10 0C CB 5E FD BA CB 5E F3 47 04 07 00 17 00 0D 12 CB 00 00 00 00 60 02 20 00 D9 70 00 00 02 04 05 B4 2D

Интересный момент в том, откуда берется SYN. SYN образуется от первоначального номера очереди
(ISN) — это 32-битный номер от 1 до 4294967295 (2 в 32-ой степени). ISN при перезагрузке системы равен 1, затем каждую секунду он увеличивается на 128000 (строго говоря изменение происходит каждые 4 микросекунды) + при каждом установленном соединении он увеличивается на 64000. Получается, что цикл уникальности ISN, при условии того, что никакие соединения не устанавливались, составляет примерно 4,55 часа. Поскольку ни один пакет так долго по сети не путешествует, мы можем полагать, что SYN будет абсолютно уникальным.

Получив наш пакет, удаленная система отвечает, что получила и готова установить соединение. Данные пакет выглядит так:

Host — SYN (758684758) и ACK (856780) — Client

Как видишь, удаленная система дает понять, что получила наш пакет. Для этого она посылает нам ACK с номером «наш SYN+1». В добавок к этому удаленная система посылает нам свой SYN (мы же тоже будем отвечать). А ответ наш будет такой:

Client — SYN (856780) и ACK (758684759) — Host

Думаю тебе уже должно быть все понятно. Если кто не понял, то пакет означает следующее: ваш пакет с SYN (758684758) получен, соединение установлено, наш SYN равен 856780.

Эту процедуру называют «трехкратным подтверждением» или «трехкратным рукопожатием». Первые два этапа необходимы для синхронизации SYN наших систем, а третий — подтверждение того, что синхронизация произошла.

Далее у нас идет обмен данными, т.е. то, для чего соединение и устанавливалось. Причем надо заметить, что на всех стадиях обеспечение сохранности данных, передаваемых с использованием протокола TCP, осуществляется следующим образом: посланный пакет помещается в буфер и если за определенное время от удаленной системы не приходит пакет с подтверждением (ACK), то пакет посылается снова; если же подтверждение пришло, то пакет считается посланным успешно и удаляется из буфера.

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

Client — FIN(4894376) и ACK (1896955378) — Host

Host — ACK (4894377) — Client

Host — FIN (1896955378) и ACK (4894377) — Client

Client — ACK (1896955378) — Host

Думаю, ничего сложного здесь нет. Единственное, что стоит отметить — это флаг FIN, который означает желание завершить соединение.

Подводя небольшие итоги вышеизложенному, отметим в каких же случаях изменяются/не изменяются порядковые номера:

Передача одного FIN Пакета = +1
Передача одного SYN Пакета = +1
Передача одного ACK Пакета = 0
Передача одного SYN/ACK Пакета = +1
Передача одного FIN/ACK Пакета = +1
Изменение за 1 секунду = +128,000
Установление одного соединения = +64,000

Возможно, кто-то спросит: «А что будет, если машин получит пакет с таким ACK, которого не было?» (SYN=ACK-1, а пакет с таким SYN мы не посылали). Получив ответ непонятно на что, мы в свою очередь ответим удаленной системе NACK-пакетом (означает «не знаю о чем ты», никакого соединения не устанавливается), но, надеюсь, более подробно мы поговорим с тобой об этом в следующий раз.

Говорят, что протокол TCP осуществляет передачу с установлением логического соединения, поскольку перед началом обмена данными два процесса осуществляют «рукопожатие» - процедуру, заключающуюся в передаче друг другу специальных сегментов, предназначенных для определения параметров обмена данными. Частью процедуры установления TCP-соединения является инициализация переменных состояния (многие из которых будут рассмотрены в этом разделе и разделе «Контроль перегрузок в ТСР»), связанных с ТСР-соединением.

TCP-соединение не является «соединением» в том смысле, в каком этот термин употребляется в коммутируемых сетях. Оно также не является виртуальным каналом (см. главу 1), поскольку наблюдение за его состоянием ведется обеими сторонами. Поскольку протокол TCP выполняется на оконечных системах и не выполняется на промежуточных сетевых устройствах (маршрутизаторах и мостах), последние не отслеживают состояния TCP-соединения. Более того, маршрутизаторы не «знают» о существовании TCP-соединения: их работа выполняется на уровне дейтаграмм.

TCP-соединение обеспечивает дуплексную передачу данных. Если на двух хостах выполняются соответственно процессы А и В, то данные могут одновременно передаваться как от процесса А к процессу В, так и от процесса В к процессу А. ТСР-соединение также называют соединением точка-точка, то есть соединением между единственным приемником и единственным передатчиком. Групповая рассылка, описанная в главе 4, позволяет передавать данные сразу множеству адресатов с помощью одной операции, однако такая рассылка не поддерживается протоколом TCP.

Теперь давайте подробнее рассмотрим процесс установления ТСР-соединения. Предположим, что процесс, выполняющийся на одном хосте, желает установить соединение с процессом, выполняющимся на другом хосте. Вспомним о том, что процесс, инициирующий соединение, мы договорились называть клиентским, а процесс, с которым устанавливается соединение, - серверным. Сначала клиентский процесс сообщает транспортному уровню своего хоста о том, что необходимо установить соединение с серверным процессом. Обратившись к разделу «Программирование ТСР-сокетов» в главе 2, можно увидеть, что программа-клиент на языке Java делает это при помощи следующей команды:

Socket clientSocket = new Socket(«hostname», portNumber);

Здесь hostname - имя сервера, a portNumber - номер порта, идентифицирующий процесс внутри сервера. Затем транспортный уровень клиента начинает установление TCP-соединения с транспортным уровнем сервера. Эту процедуру мы детально рассмотрим в конце этого раздела, а пока нам достаточно знать, что клиент сначала посылает серверу специальный TCP-сегмент, сервер отвечает клиенту другим специальным сегментом, и, наконец, клиент посылает серверу третий специальный сегмент. Первые два сегмента не содержат данных прикладного уровня; третий сегмент может содержать их. Поскольку обмен сегментами входит в процедуру установления соединения, последнюю часто называют тройным рукопожатием.

После того как TCP-соединение установлено, прикладные процессы могут начинать обмен данными. Передача данных от клиента к серверу происходит следующим образом: клиент направляет поток своих данных в сокет («дверь» процесса), как описано в разделе «Программирование ТСР-сокетов» главы 2. Через сокет данные попадают в протокол TCP, выполняющийся на стороне клиента. Как показано на рис. 3.25, TCP направляет эти данные в буфер передачи - один из буферов, создаваемых при выполнении тройного рукопожатия. Время от времени TCP извлекает данные из буфера передачи. Интересной особенностью спецификации TCP (RFC 793) является свобода в выборе моментов отправки данных, находящихся в буфере. Согласно спецификации, протокол TCP должен «передать эти данные в виде сегментов в любой подходящий для этого момент времени». Максимальный объем данных, который может быть извлечен из буфера и помещен в сегмент, ограничивается максимальным размером сегмента (Maximum Segment Size, MSS). Максимальный размер сегмента зависит от реализации протокола TCP (определяется операционной системой) и может быть сконфигурирован; наиболее часто используются значения 1500,536 и 512 байт (размер сегмента часто устанавливается так, чтобы избежать IP-фрагментации, которая будет рассмотрена позже в этой главе). Обратите внимание на то, что максимальный размер относится к данным приложения, содержащимся в сегменте, а не к сегменту вместе с заголовком (такая терминология является несколько запутанной, однако мы вынуждены придерживаться этой терминологии ввиду ее распространенности).

Протокол TCP добавляет заголовок к каждому фрагменту данных, формируя TCP-сегменты. Сегменты передаются сетевому уровню, где заключаются в IP-дейтаграммы. Дейтаграммы пересылаются по сети и принимаются получателем. Когда сегмент оказывается на транспортном уровне, протокол TCP помещает данные сегмента в приемный буфер, как и показано на рисунке. Затем приложение считывает поток данных из буфера. Приемный и передающий буферы имеются на обеих сторонах соединения (мы рекомендуем читателю обратиться к апплету, который находится на нашем сайте _http://www.awl.com/kurose-ross и позволяет просмотреть анимацию, иллюстрирующую работу приемного и передающего буферов).
Итак, TCP-соединение состоит из буферов и переменных на передающей и принимающей сторонах, а также сокетного соединения между сторонами. При этом для соединения не выделяется никаких буферов или переменных на промежуточных сетевых устройствах (маршрутизаторах, мостах и повторителях).

ИСТОРИЧЕСКАЯ СПРАВКА —
В начале 1970-х годов стали получать распространение сети с коммутацией пакетов. Сеть APRAnet, предок Интернета, была одной из таких сетей. В каждой сети использовался собственный протокол. Двое исследователей, Уинтон Серф и Роберт Канн, понимая важность взаимодействия компьютерных сетей между собой, разработали межсетевой протокол TCP/IP (Transmission Control Protocol/Internet Protocol - протокол управления передачей/Интернет-протокол). Несмотря на то что изначально TCP/IP представлял собой единую сущность, позже он был разделен на две части, TCP и IR каждая из которых функционировала независимо. В мае 1974 года Серфом и Канном были выпущены публикации в IEEE Transaction on Communication Technology.

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

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

Реализации TCP обычно встроены в ядра ОС . Существуют реализации TCP, работающие в пространстве пользователя .

Когда осуществляется передача от компьютера к компьютеру через Интернет, TCP работает на верхнем уровне между двумя конечными системами, например, браузером и веб-сервером. TCP осуществляет надёжную передачу потока байтов от одного процесса к другому. TCP реализует управление потоком, управление перегрузкой, рукопожатие, надежную передачу.

Заголовок сегмента TCP

Структура заголовка
Бит 0 - 3 4 - 9 10 - 15 16 - 31
0 Порт источника, Source Port Порт назначения, Destination Port
32 Порядковый номер, Sequence Number (SN)
64 Номер подтверждения,
96 Длина заголовка Зарезервировано Флаги Размер Окна
128 Контрольная сумма Указатель важности
160 Опции (необязательное, но используется практически всегда)
160/192+ Данные

Порт источника, Порт назначения

Эти 16-битные поля содержат номера портов - числа, которые определяются по специальному списку .

Порт источника идентифицирует приложение клиента, с которого отправлены пакеты. Ответные данные передаются клиенту на основании этого номера.

Порт назначения идентифицирует порт, на который отправлен пакет.

Порядковый номер

Порядковый номер выполняет две задачи:

  1. Если установлен флаг SYN, то это изначальный порядковый номер - ISN (Initial Sequence Number), и первый байт данных, которые будут переданы в следующем пакете, будет иметь номер, равный ISN + 1.
  2. В противном случае, если SYN не установлен, первый байт данных, передаваемый в данном пакете, имеет этот порядковый номер

Поскольку поток TCP в общем случае может быть длиннее, чем число различных состояний этого поля, то все операции с порядковым номером должны выполняться по модулю 2 32 . Это накладывает практическое ограничение на использование TCP. Если скорость передачи коммуникационной системы такова, чтобы в течение MSL (максимального времени жизни сегмента) произошло переполнение порядкового номера, то в сети может появиться два сегмента с одинаковым номером, относящихся к разным частям потока, и приёмник получит некорректные данные.

Номер подтверждения

Acknowledgment Number (ACK SN) (32 бита) - если установлен флаг ACK, то это поле содержит порядковый номер октета, который отправитель данного сегмента желает получить. Это означает, что все предыдущие октеты (с номерами от ISN+1 до ACK-1 включительно) были успешно получены.

Длина заголовка (смещение данных)

Длина заголовка (Data offset) занимает 4 бита и указывает значение длины заголовка, измеренное в 32-битовых словах. Минимальный размер составляет 20 байт (пять 32-битовых слов), а максимальный - 60 байт (пятнадцать 32-битовых слов). Длина заголовка определяет смещение полезных данных относительно начала сегмента. Например, Data offset равное 1111 говорит о том, что заголовок занимает пятнадцать 32-битных слова (15 строк*32 бита в каждой строке/8 бит = 60 байт).

Зарезервировано

Зарезервировано (6 бит) для будущего использования и должно устанавливаться в ноль. Из них два (5-й и 6-й) уже определены:

  • CWR (Congestion Window Reduced) - Поле «Окно перегрузки уменьшено» - флаг установлен отправителем, чтобы указать, что получен пакет с установленным флагом ECE (RFC 3168)
  • ECE (ECN-Echo) - Поле «Эхо ECN» - указывает, что данный узел способен на ECN (явное уведомление перегрузки) и для указания отправителю о перегрузках в сети (RFC 3168)

Флаги (управляющие биты)

Это поле содержит 6 битовых флагов:

  • URG - поле «Указатель важности» задействовано (англ. Urgent pointer field is significant )
  • ACK - поле «Номер подтверждения» задействовано (англ. Acknowledgement field is significant )
  • PSH - (англ. Push function ) инструктирует получателя протолкнуть данные, накопившиеся в приёмном буфере, в приложение пользователя
  • RST - оборвать соединения, сбросить буфер (очистка буфера) (англ. Reset the connection )
  • SYN - синхронизация номеров последовательности (англ. Synchronize sequence numbers )
  • FIN (англ. final , бит) - флаг, будучи установлен, указывает на завершение соединения (англ. FIN bit used for connection termination ).

Размер окна

Количество байт данных начиная с последнего номера подтверждения, которые может принять получатель данного пакета. Иначе говоря, получатель пакета располагает для приёма данных буфером длиной "размер окна" байт.

Контрольная сумма

Поле контрольной суммы - это 16-битное дополнение к сумме всех 16-битных слов заголовка (включая псевдозаголовок) и данных. Если сегмент, по которому вычисляется контрольная сумма, имеет длину не кратную 16-ти битам, то длина сегмента увеличивается до кратной 16-ти, за счёт дополнения к нему справа нулевых битов заполнения. Биты заполнения (0) не передаются в сообщении и служат только для расчёта контрольной суммы. При расчёте контрольной суммы значение самого поля контрольной суммы принимается равным 0.

Указатель важности

16-битовое значение положительного смещения от порядкового номера в данном сегменте. Это поле указывает порядковый номер октета, которым заканчиваются важные (urgent) данные. Поле принимается во внимание только для пакетов с установленным флагом URG. Используется для внеполосных данных .

Опции

Могут применяться в некоторых случаях для расширения протокола. Иногда используются для тестирования. На данный момент в опции практически всегда включают 2 байта NOP (в данном случае 0x01) и 10 байт, задающих timestamps . Вычислить длину поля опции можно через значение поля смещения.

Механизм действия протокола

В отличие от традиционной альтернативы - UDP, который может сразу же начать передачу пакетов, TCP устанавливает соединения, которые должны быть созданы перед передачей данных. TCP соединение можно разделить на 3 стадии:

  • Установка соединения
  • Передача данных
  • Завершение соединения

Состояния сеанса TCP

Состояния сеанса TCP
CLOSED Начальное состояние узла. Фактически фиктивное
LISTEN Сервер ожидает запросов установления соединения от клиента
SYN-SENT Клиент отправил запрос серверу на установление соединения и ожидает ответа
SYN-RECEIVED Сервер получил запрос на соединение, отправил ответный запрос и ожидает подтверждения
ESTABLISHED Соединение установлено, идёт передача данных
FIN-WAIT-1 Одна из сторон (назовём её узел-1) завершает соединение, отправив сегмент с флагом FIN
CLOSE-WAIT Другая сторона (узел-2) переходит в это состояние, отправив, в свою очередь сегмент ACK и продолжает одностороннюю передачу
FIN-WAIT-2 Узел-1 получает ACK, продолжает чтение и ждёт получения сегмента с флагом FIN
LAST-ACK Узел-2 заканчивает передачу и отправляет сегмент с флагом FIN
TIME-WAIT Узел-1 получил сегмент с флагом FIN, отправил сегмент с флагом ACK и ждёт 2*MSL секунд, перед окончательным закрытием соединения
CLOSING Обе стороны инициировали закрытие соединения одновременно: после отправки сегмента с флагом FIN узел-1 также получает сегмент FIN, отправляет ACK и находится в ожидании сегмента ACK (подтверждения на свой запрос о разъединении)

Установка соединения

Процесс начала сеанса TCP (также называемый «рукопожатие» (англ. handshake )), состоит из трёх шагов.

1. Клиент, который намеревается установить соединение, посылает серверу сегмент с номером последовательности и флагом SYN.

  • Сервер получает сегмент, запоминает номер последовательности и пытается создать сокет (буферы и управляющие структуры памяти) для обслуживания нового клиента.
    • В случае успеха сервер посылает клиенту сегмент с номером последовательности и флагами SYN и ACK, и переходит в состояние SYN-RECEIVED.
    • В случае неудачи сервер посылает клиенту сегмент с флагом RST.

2. Если клиент получает сегмент с флагом SYN, то он запоминает номер последовательности и посылает сегмент с флагом ACK.

  • Если клиент одновременно получает и флаг ACK (что обычно и происходит), то он переходит в состояние ESTABLISHED.
  • Если клиент получает сегмент с флагом RST, то он прекращает попытки соединиться.
  • Если клиент не получает ответа в течение 10 секунд, то он повторяет процесс соединения заново.

3. Если сервер в состоянии SYN-RECEIVED получает сегмент с флагом ACK, то он переходит в состояние ESTABLISHED.

  • В противном случае после тайм-аута он закрывает сокет и переходит в состояние CLOSED.

Процесс называется «трёхэтапным согласованием» (англ. three way handshake ), так как несмотря на то что возможен процесс установления соединения с использованием четырёх сегментов (SYN в сторону сервера, ACK в сторону клиента, SYN в сторону клиента, ACK в сторону сервера), на практике для экономии времени используется три сегмента.

Пример базового 3-этапного согласования:

TCP A TCP B 1. CLOSED LISTEN 2. SYN-SENT --> --> SYN-RECEIVED 3. ESTABLISHED <-- <-- SYN-RECEIVED 4. ESTABLISHED --> --> ESTABLISHED 5. ESTABLISHED <-- <-- ESTABLISHED

В строке 2 TCP A начинает передачу сегмента SYN, говорящего об использовании номеров последовательности, начиная со 100. В строке 3 TCP B передаёт SYN и подтверждение для принятого SYN в адрес TCP A. Надо отметить, что поле подтверждения показывает ожидание TCP B приёма номера последовательности 101, подтверждающего SYN с номером 100.

В строке 4 TCP A отвечает пустым сегментом с подтверждением ACK для сегмента SYN от TCP B; в строке 5 TCP B передаёт некоторые данные. Отметим, что номер подтверждения сегмента в строке 5 (ACK=101) совпадает с номером последовательности в строке 4 (SEQ=101), поскольку ACK не занимает пространства номеров последовательности (если это сделать, придётся подтверждать подтверждения - ACK для ACK).

Передача данных

При обмене данными приёмник использует номер последовательности, содержащийся в получаемых сегментах, для восстановления их исходного порядка. Приёмник уведомляет передающую сторону о номере последовательности, до которой он успешно получил данные, включая его в поле «номер подтверждения». Все получаемые данные, относящиеся к промежутку подтверждённых последовательностей, игнорируются. Если полученный сегмент содержит номер последовательности больший, чем ожидаемый, то данные из сегмента буферизируются, но номер подтверждённой последовательности не изменяется. Если впоследствии будет принят сегмент, относящийся к ожидаемому номеру последовательности, то порядок данных будет автоматически восстановлен исходя из номеров последовательностей в сегментах.

Для того, чтобы передающая сторона не отправляла данные интенсивнее, чем их может обработать приёмник, TCP содержит средства управления потоком. Для этого используется поле «окно». В сегментах, направляемых от приёмника передающей стороне, в поле «окно» указывается текущий размер приёмного буфера. Передающая сторона сохраняет размер окна и отправляет данных не более, чем указал приёмник. Если приёмник указал нулевой размер окна, то передача данных в направлении этого узла не происходит, пока приёмник не сообщит о большем размере окна.

В некоторых случаях передающее приложение может явно затребовать протолкнуть данные до некоторой последовательности принимающему приложению, не буферизируя их. Для этого используется флаг PSH. Если в полученном сегменте обнаруживается флаг PSH, то реализация TCP отдаёт все буферизированные на текущий момент данные принимающему приложению. «Проталкивание» используется, например, в интерактивных приложениях. В сетевых терминалах нет смысла ожидать ввода пользователя после того, как он закончил набирать команду. Поэтому последний сегмент, содержащий команду, обязан содержать флаг PSH, чтобы приложение на принимающей стороне смогло начать её выполнение.

Завершение соединения

Завершение соединения можно рассмотреть в три этапа:

  1. Посылка серверу от клиента флага FIN на завершение соединения.
  2. Сервер посылает клиенту флаги ответа ACK , FIN, что соединение закрыто.
  3. После получения этих флагов клиент закрывает соединение и в подтверждение отправляет серверу ACK , что соединение закрыто.

Известные проблемы

Максимальный размер сегмента

TCP требует явного указания максимального размера сегмента (MSS) в случае, если виртуальное соединение осуществляется через сегмент сети, где максимальный размер блока (MTU) менее, чем стандартный MTU Ethernet (1500 байт).

В протоколах туннелирования, таких как GRE , IPIP , а также PPPoE MTU туннель меньше, чем стандартный, поэтому сегмент TCP максимального размера имеет длину пакета больше, чем MTU. Это приводит к фрагментации и уменьшению скорости передачи полезных данных. Если на каком-либо узле фрагментация запрещена, то со стороны пользователя это выглядит как «зависание» соединений. При этом «зависание» может происходить в произвольные моменты времени, а именно тогда, когда отправитель использовал сегменты длиннее допустимого размера. Для решения этой проблемы на маршрутизаторах применяются правила Firewall-а, добавляющие параметр MSS во все пакеты, инициирующие соединения, чтобы отправитель использовал сегменты допустимого размера.

MSS может также управляться параметрами операционной системы.

Обнаружение ошибок при передаче данных

Хотя протокол осуществляет проверку контрольной суммы по каждому сегменту, используемый алгоритм считается слабым . Так, в 2008 году ошибка в передаче одного бита, не обнаруженная сетевыми средствами, привела к остановке серверов системы Amazon Web Services .

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

Атаки на протокол

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

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

Шаг 1. Отправка SYN пакета

Отправляется пакет с выставленным флагом SYN, что означает инициализацию сессии. Разумеется, на этом этапе будет задан порт источника и порт назначения (порт источника выбирается случайно из диапазона 1024-65535), хотя на этом участке можно выделить два диапазона ещё. Порты с 1024 до 49151 используются для проприетарных приложений, контролируется IANA (те же чуваки, которые и выделяют IP адреса). Порт назначения здесь зависит от используемой службы. Стандартные порты ssh – 22, http – 80, pop3 – 110 и т.д. Все эти порты прописаны в c:\Windows\System32\drivers\etc\services ну или аналогичный файл в Linux.

SYN

Как же выбирается этот номер? Приведу выдержку из RFC 793:

При организации нового соединения генерируется начальный порядковый номер (initial sequence number) ISN. Генерация номера основана на текущем (возможно, фиктивном) 32-битовом значении времени, в котором младший бит инкрементируется приблизительно каждые 4 микросекунды. Таким образом, цикл номеров ISN занимает около 4.55 часа. Поскольку мы предполагаем, что сегмент сохраняется в сети в течение времени, не превышающего MSL (Maximum Segment Lifetime – максимальное время жизни

сегмента), и значение MSL < 4.55 час., можно считать значения ISN уникальными.

То есть в первом пакете с битом SYN задается некий номер последовательности. На скрине выше я привел пример, видим бит SYN и ISN 2686526190 .

Шаг 2. Отправка подтверждения SYN+ACK

В ответ на этот пакет, сервер, если он не против соединения, посылает пакет с битами SYN,ACK и произвольным номером последовательности Sequence Number, вычисленным по похожему принципу. А поле Acknowledgment Number будет равняться полю ISN+1.


На примере видно, что сгенерировано число Initial Receive Sequence (IRS) = 675813843 и пакет послан как ответ AN: 2686526191 (предыдущий SN: 2686526190 + 1).

Шаг 3. Отправка подтверждения ACK

Теперь инициатору подключения не остается ничего другого, как ответить ACK и пояснить, что речь идёт об Acknowledgment number предыдущего шага IRS + 1, т.е. 675813843+1 = 675813844! А Sequence nuber остаётся неизменным, AN предыдущего пакета 2686526191.


ACK

Иначе, в переводе с TCP на русский это выглядит так:

  1. Клиент: Кодовое слово “1” (Sequence number), сервер, давай мутить! (SYN);
  2. Сервер: Моё кодовое слово “5” (Sequence number), клиент, на твой запрос по кодовому слову “1” (Acknowledgment number) отвечаю (+1) ну давай мутить (SYN+ACK).
  3. Клиент: Ну хорошо! Раз ты, сервер, получай мой окончательный ответ ответ (ACK) на твое согласие (5+1) на мой запрос (1+1).

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

При этому так же происходит взаимное увеличение Sequence Number у сервера и у клиента, но только уже не на 1, а на размер отправляемых данных.