Представить современный мир без компьютерных сетей практически невозможно. Компьютерные сети, или сети передачи данных, проникли практически во все области жизни человека: теперь мы можем общаться, несмотря на расстояние, с лёгкостью записываться на прием к врачу и не носить с собой полный денег бумажник — все это и многое другое нам дали компьютерные сети. Они стали результатом слияния двух технологий: компьютерной (распределенная вычислительная система, в которой группа компьютеров согласованно выполняет набор взаимосвязанных задач, обмениваясь данными в автоматическом режиме) и телекоммуникационной (средство передачи информации на большие расстояния с использованием методов кодирования и мультиплексирования данных). Наиболее популярной на данной момент компьютерной сетью, которой пользуются более трех миллиардов человек по всему миру [2], является сеть Интернет. Данная компьютерная сеть построена на стеке протоколов TCP/IP (данный стек, разработанный по инициативе Министерства обороны США, изначально создавался для Интернета, чем и обеспечил себе преимущество при построении сетей, включающих глобальные связи). Считается, что 1 января 1983 года, в день, когда всемирно известная сеть ARPANET перешла на работу с новыми протоколами стека TCP/IP, родился Интернет. Самую важную роль в семействе протоколов TCP/IP играют протокол управления передачей данных, или протокол TCP [4], и межсетевой протокол, или протокол IP [6]. Именно первый из них, являющийся так называемым «старшим братом» в семействе, и будет рассмотрен в дальнейшем.
Как было сказано выше, протокол TCP отвечает за выполнение крайне важной задачи — управления передачей данных. Если рассматривать данный протокол с точки зрения эталонной модели OSI [1] (определяет уровни взаимодействия систем в сетях с коммутацией пакетов, стандартные названия уровней, а также функции, которые должен выполнять каждый уровень; всего этих уровней семь: прикладной уровень, уровень представления, сеансовый уровень, транспортный уровень, сетевой уровень, канальный уровень и физический уровень), то он работает на сеансовом (обеспечивает управление взаимодействием сторон: фиксирует, какая из сторон является активной в настоящий момент, и предоставляет средства синхронизации сеанса) и транспортном уровнях (обеспечивает приложениям или верхним уровням стека передачу данных с той степенью надежности, которая им требуется). Если же рассматривать его с точки зрения стека TCP/IP (в стеке TCP/IP определены четыре уровня: прикладной уровень, транспортный уровень, сетевой уровень и уровень сетевых интерфейсов), то он работает на транспортном уровне. Это обуславливает то, что протокол TCP, обеспечивая гарантированную доставку, принимает от прикладного уровня задание на передачу данных с тем или иным качеством, докладывая после выполнения операции, а также то, что протокол TCP рассматривает уровень межсетевого взаимодействия, как инструмент, не очень надежный, но способный перемещать пакет по составной сети.
Поступающая к протоколу TCP информация от протоколов более высокого уровня рассматривается им как неструктурированный поток байтов [1]. Для передачи на сетевой уровень данный поток нарезается непрерывными кусками, называемыми сегментами. К каждому TCP-сегменту прибавляется заголовок, в состав которого входят следующие поля: порт источника, порт приемника, последовательный номер, подтвержденный номер, длина заголовка, резерв, кодовые биты, окно, контрольная сумма, указатель срочности, параметры и заполнитель.
Обеспечение надежной доставки сообщений [5] достигается протоколом TCP благодаря установлению логических соединений, с помощью которых он следит, чтобы передаваемые сегменты не были потеряны, продублированы или доставлены в неправильном порядке. При установлении логического соединения стороны отправляют друг другу следующую информацию: наибольший размер сегмента, который каждая сторона готова принимать; максимальный объем данных, который каждая сторона разрешает противоположной передавать в свою сторону; начальный порядковый номер байта, с которого начинает отсчет потока данных в рамках данного соединения. Логическое TCP-соединение однозначно идентифицируется парой сокетов. Правильность передачи каждого сегмента подтверждается квитанцией от получателя.
Протокол TCP обеспечивает обмен сегментами в обе стороны. В связи с этим на каждой из них имеются три буфера: буфер хранения принятых сегментов, буфер хранения готовых к отправке сегментов и буфер хранения копий отправленных сегментов, для которых еще не была получена квитанция. Для урегулирования процедуры отправления сегментов на основе наполненности буферов каждая из сторон посылает другой окно приема. В данном окне указывается число байтов, которое готова принимать сторона с момента получения последней квитанции. Окно приема, являясь зависимым от состояния буферов, может постоянно изменяться, что существенно влияет на загрузку сети. С увеличением размера окна увеличивается число сегментов, которые можно отправить. Но, к сожалению, увеличивать окно до бесконечности нельзя. Как только его размер станет больше, чем тот, который может принять TCP-модуль, то произойдет потеря сегментов. Из-за этого потребуется повторная пересылка утерянных сегментов, что увеличит нагрузку как на сеть, так и на TCP-модуль.
Несмотря на свою популярность и надежность, протокол TCP не смог и не сможет вытеснить из стека TCP/IP другой протокол транспортного уровня — протокол UDP [1]. Протокол UDP никоим образом не гарантирует доставку сообщений, предоставляя сервис по возможности. То есть протокол UDP, в отличие от протокола TCP, не обращает никакого внимания на утерю пакетов, даже несмотря на их количество. Однако в некоторых случаях этот недостаток с лихвой компенсируется практическими преимуществами. Так, например, представить работу телевидения или широковещательного сообщения по протоколу TCP невозможно из-за необходимости установления огромного числа логических соединений. Также из-за своей простоты и быстроты протокол UDP используется тогда, когда необходимый уровень надежности достигается высоким качеством лини связи, что позволяет не применять таких действий, как установление логического соединения или квитирование.
Нельзя не упомянуть и про недостатки протокола TCP. К их числу относятся:
1) Слабый уровень защиты от атаки злоумышленников;
2) Отсутствие инструментов, обеспечивающих оптимальное использование логического соединения при перегрузках;
3) Неэффективные механизмы установления соединения и разрыва связи;
4) Низкий уровень адаптивности к изменениям ситуации в сети;
5) Низкая приспособленность к работе со скоростными каналами;
6) Возможность нормального функционирования при соблюдении ряда условий.
Именно из-за недостатка, указанного в пункте 6, понадобилось принимать специальные меры по балансировке загрузки каналов. В связи с этим было разработано несколько разновидностей протокола TCP, каждый из которых использует прогноз поведения канала в будущем. Данный прогноз формирует отправитель на основе данных, полученных им ранее. Прежде чем рассмотреть различные виды протокола TCP, необходимо обговорить условия, при выполнении которых данный протокол функционирует нормально. Данные условия приведены ниже:
1) Низкая вероятность ошибки доставки, потеря сегмента вероятнее всего происходит из-за переполнения буфера;
2) Стабильное время доставки, рассчитать которое можно используя линейную аппроксимацию;
3) Фиксированная полоса пропускания сети, для которой не допускается скачкообразный характер;
4) Использование буферами схемы FIFO (первым пришел — первым вышел);
5) Отсутствие коротких TCP-сессий, снижающих эффективность обмена данными;
6) Большой объем поля данных;
7) Отсутствие разрушительного взаимодействия, приводящего к резкому снижению эффективности виртуального канала, между различными TCP-сессиями.
Как было указано выше, из-за необходимости выполнять условия нормального функционирования пришлось разработать несколько видов протокола TCP. В настоящий момент более всего известны следующие вариации: TCPTahoe, TCPReno (TCPNewReno), TCPVegas, BICTCP, CUBICTCP, HighspeedTCP и многие другие. Каждый из них начинает работу при определенном прогнозе поведения канала.
Алгоритм TCPTahoe [3] был разработан в 1988 году. При переполнении буфера происходит потеря пакетов, после чего начинается медленный старт. В фазе медленного старта пороговое значение становится равным размеру окна в момент, когда произошел таймаут, а размер окна становится равным единице. После получения каждой квитанции размер окна увеличивается на единицу, пока не достигнет порогового значения. При достижении же порогового значения при получении квитанции к размеру окна прибавляется величина, обратная ему (то есть рост становится линейным). Суть алгоритма заключается в нахождении и удержании максимально возможного размера окна. Основной недостаток данного алгоритма заключается в том, что неизвестно, по какой причине был утерян пакет. Так, если бы сегмент был утерян из-за переполнения буфера, то размер окна можно было бы просто уменьшить на единицу. Но если бы сегмент был утерян из-за начала TCP-сессии с другим клиентом, то размер окна необходимо было бы уменьшить до единицы, чтобы не вызвать блокировки канала и резкого падения скорости передачи.
TCP Reno [3] был разработан в 1990 году. Он применялся во всех операционных системах Windows вплоть до версии XP. Особенностью данного алгоритма является циклическое изменение размера окна при нормальных условиях, пока не произойдет потеря сегмента. TCPReno находится в фазе медленного старта, когда размер окна меньше определенного граничного значения числа сегментов, при котором происходит переход на фазу исключения перегрузки. В фазе медленного старта при получении квитанции, подтверждающей доставку, окно увеличивается на единицу. В фазе же исключения перегрузки в той же ситуации получения квитанции окно увеличивается на величину, обратную самому себе. Если во время таймаута удается обнаружить потерю сегмента, то пороговое число сегментов становится равным половине размера окна в данный момент, а размер окна становится равным единице (при использовании алгоритма быстрой повторной передачи размер окна становится равным новому пороговому числу сегментов). Сразу после этого происходит переход в фазу быстрого восстановления, в которой размер окна увеличивается на единицу только тогда, когда приходит дублированное подтверждение. Если же приходит недублированный отклик от сегмента, отправленного повторно, то размер окна становится равным пороговому числу сегментов. При таймауте в данной фазе значения размера окна и порогового числа сегментов обновляются, как при потере сегмента.
Современной версией алгоритма TCPReno является алгоритм TCPNewReno. Он превосходит своего предшественника во всем, уступая лишь в случае, когда происходит изменение порядка следования сегментов. Данный алгоритм улучшает повторную передачу во время фазы быстрого восстановления. При получении дублированного подтверждения отправляется новый сегмент для поддержания полного заполнения окна. Каждая квитанция также увеличивает размер окна на единицу. Это, а также то, что при успешном отправлении пакета таймер таймаута сбрасывается, позволяет поддерживать высокую пропускную способность.
Совсем иначе себя ведет разработанный в 1994 году алгоритм TCPVegas [3]. Он оперирует временем, которое определяется, как сумма времени доставки сегмента от отправителя получателю и времени доставки квитанции от получателя отправителю. Если это время увеличивается, то согласно алгоритму система понимает, что сеть приближается к перегрузке и уменьшает размер окна. Если же это время начинает уменьшаться, то согласно алгоритму система понимает, что сеть преодолела перегрузку и увеличивает размер окна. То есть можно сказать, что в каждый момент времени система стремится к тому, чтобы размер окна был оптимальным в текущих условиях загрузки сети.
Алгоритм BICTCP, его последующая модификация алгоритм CUBICTCP, алгоритм HighspeedTCP и некоторые другие алгоритмы являются алгоритмами, созданными для длинных и быстрых сетей, имеющих большое время доставки сегмента и получения квитанции об успешной доставке. Так алгоритм BICTCP, управляя перегрузкой, пытается найти такое значение размера окна, которое будет возможно удерживать в течение максимально возможного времени. Использует он при этом двоичный поиск. В свою очередь, алгоритм CUBICTCP изменяет размер окна по кубическому закону, зависящему от того, как давно произошла последняя потеря пакета, а также от того, каким был размер окна при этой потере. В этом заключается ключевая особенность алгоритма CUBICTCP, ведь согласно ему размер окна больше не зависит от получения квитанций, а зависит только от того, что случилось при последней потере пакета. Алгоритм HighspeedTCP позволяет лучше использовать доступную полосу пропускания канала, внося незначительные изменения в механизм управления перегрузкой стандартного протокола TCP.
Таким образом, можно сказать, что протокол TCP, являющийся одним из важнейших звеньев в современном Интернете, хоть и не лишен недостатков, но может их обходить. Для этого необходимо понимать, для каких целей используется тот или иной канал передачи данных, а также иметь прогноз поведения этого канала. Однако одно можно сказать точно — надежность, обеспечиваемая протоколом TCP, будет и дальше позволять ему играть огромную роль в современных компьютерных сетях.
Литература:
- Олифер, В. Г. Компьютерные сети / В. Г. Олифер, Н. А. Олифер. — СПб.: Издательский дом «Питер», 2006. — 958 с.
- Международный союз электросвязи, пресс-релиз. // Электронный ресурс. URL: http://www.itu.int/en/ITU-D/Statistics/Pages/facts/default.aspx (дата обращения: 22.06.2016).
- Семенов, Ю. А. Телекоммуникационные технологии. // Электронный ресурс. URL: http://book.itep.ru/preword.htm (дата обращения: 22.06.2016).
- Стандарт RFC 793. // Электронный ресурс. URL: https://tools.ietf.org/html/rfc793 (дата обращения: 22.06.2016).
- Федорук, В. Г. Протоколы сетевого взаимодействия TCP/IP. // Электронный ресурс. URL: https://www.opennet.ru/docs/RUS/tcpip (дата обращения: 22.06.2016).
- Стандарт RFC 791. // Электронный ресурс. URL: https://tools.ietf.org/html/rfc791 (дата обращения: 22.06.2016).