
В первых трех сегментах мы наблюдаем уже привычную процедуру установки TCP
соединения. В четвертом сегменте клиент передает серверу 7 байт данных (6 символов «нуль» и
символ начала новой строки). Пятый сегмент как раз и иллюстрирует квитанцию и полезные
данные, объединенные в одном сегменте. Действительно, анализатор подсказывает нам, что данный
сегмент является квитанцией на сегмент номер четыре, видно, что относительный Acknowledged
Number этого сегмента – 8, т.е. квитируется 7 байт данных, кроме того видно, что данный сегмент
сам несет 7 байт данных – сетевая служба Echo возвращает клиенту полученные от него данные. В
сегменте 6 клиент отправляет серверу квитанцию на эти 7 байт, полученных от сервера, а в
сегменте 7 клиент передает серверу новые данные. Почему же сервер может объединить в сегменте
5 квитанцию и полезные данные, а клиент передает подряд два сегмента (6 и 7) вместо того, чтобы
их объединить? Дело в том, что когда сервер получает данные от клиента, это приводит к генерации
и квитанции и прикладного ответа вследствие специфики работы сервера (эхо), а с клиентом другая
ситуация: полученные от сервера данные приводят к отправке квитанции, а ввод пользователя с
клавиатуры приводит к отправке новых данных. Когда клиент получает данные от сервера он готов
сгенерировать квитанцию относительно быстро, а пользователь вводит новые данные с клавиатуры
для отправки серверу с некоторой задержкой.
Важно, что при этом мы ПОКА не касаемся скользких вопросов о том, что квитанцию
генерирует стек, а прикладной ответ – процесс Echo, и, вообще говоря, даже сервер НЕ должен на
первый взгляд объединять данные и квитанции, не говорим про задержку квитанций в ожидании
попутных данных – наша цель в этой практике – закрепить изученные теоретически БАЗОВЫЕ
принципы квитирования, т.е. использование последовательных номеров и номеров подтверждений,
все, что касается вопросов оптимизации квитирования, будет рассмотрено позже!
Продолжаем рассмотрение трафика взаимодействия для закрепления понимания данного
примера, анализируем сегмент 8, который так же является объединением квитанции и данных и т.д.
Наконец, проиллюстрируем на практике возможность объединения квитанций, т.е. отправки
одной квитанции в ответ на два (или более) сегмента данных. Важно заметить, что данный пример
проиллюстрирует для нас сейчас ТОЛЬКО использование последовательных номеров и номеров
подтверждений для такого квитирования, вопросы, касающиеся стратегии удержания
подтверждений нас пока НЕ касаются. Для демонстрации нужного примера запустим утилиту sock
в качестве обычного сервера, а клиента запустим в активном режиме, т.е. заставим генерировать в
соединение некоторые произвольные данные. При этом попросим клиента дважды записать в сеть
порцию данных размером 2920 байт (т.е. каждая порция данных будет записана ровно в двух
сегментах, так как MTU нашей сети – 1500, а для TCP – 1460, поясняем, что 1460 получается путем
вычитания из MTU сети длины заголовков IP и TCP). Запустим клиента следующей командой:
c:\sock –i –n 2 –w 2920 192.168.0.89 999
Проанализируем трафик, будем обращать внимание лишь на то, что клиент передает два
сегмента с данными – сервер отвечает одной квитанцией, клиент снова передает два сегмента с
данными – сервер снова отвечает одной квитанцией.
Нас интересует в этом примере лишь использование последовательных номеров и номеров
подтверждений, нас не интересуют причины соединения квитанций, методы соединения квитанций
и т.д.– мы ДОЛЖНЫ выработать у студентов уверенный навык работы с номерами в заголовке TCP
и после того, как студенты будут уверенно ориентироваться в значениях полей Sequence Number и
Acknowledged Number в любых ситуациях, мы сможем перейти к рассмотрению тонкостей работы
TCP. Проанализируем файл TCP7cap.