Показаны сообщения с ярлыком TCP. Показать все сообщения
Показаны сообщения с ярлыком TCP. Показать все сообщения

воскресенье, 17 января 2010 г.

Где ваши гарантии?

На сайте IT Happens есть одна поучительная история о тупом завкафе и умном студенте. В ней есть одна интересная фраза, которая "как бы" говорит о том, насколько недалек завкаф и насколько умен студент.
Вот она: "C каких пор протокол TCP гарантирует доставку пакетов?"

Давайте разберемся. Честно ответьте на вопрос: а гарантирует ли TCP доставку пакетов? Все, кто ответил "да", станьте справа, те кто ответил "нет" (или "нет, но...") - слева.

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

Ребята справа (те, кто ответил "да, гарантирует"), эта встреча у нас, увы, последняя. Возможно наши дороги еще пересекутся, но сегодня нам явно не по пути. Напоследок, давайте разберемся.

Я разделил наши "разбирательства" на три этапа:

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

Этап второй: переводческий.
Будем прагматичны, обратимся к RFC.
В частности к RFC1122. Для начала я захотел понять, откуда же взялось выражение "гарантирует доставку" и произвел поиск по включению "guar". Итак, слово "guarantees" встречается в документе:

1. В разделе "1.1.3 Internet Protocol Suite" (1.1.3 Стек протоколов Internet) в описании Internet Layer, где говорится о том, что протокол IP не гарантирует доставки пакета.

2. В разделе "3.3.1.4 Dead Gateway Detection" (3.3.1.4 Обнаружение мертвых шлюзов), где говорится о том, что успешный пинг гарантирует то, что адресный интерфейс и сама машина включена, но не гарантирует того, что она будет выполнять роль шлюза.

3. В разделе "4.1.1 USER DATAGRAM PROTOCOL - UDP (INTRODUCTION)", где говорится что протокол UDP не гарантирует доставку дейтаграмм и практически предоставляет приложениям прямой доступ к протоколу IP.

На этом "гарантии" упомянутые в RFC заканчиваются. Т.е. мы понимаем, что в оригинальном документе нам никто ничего не гарантирует. Значит? Обратимся к переводу. Не уверен, существуют ли какие-то "праведные" переводы RFC (вроде Муравьевского перевода Толкиена или Маршаковского Бернса), но нам подойдет первый же выдаваемый Яндексом с сайта rfc.com.ru: RFC1122 на русском.

Поступим аналогичным образом, поищем включения "гаран". Слово "гарантированной" (и подобные), встречаются примерно в тех же местах, где и в английской версии плюс еще кое-где. Давайте посмотим эти отличающиеся моменты.

Первый раз мы сталкиваемся в том же разделе 1.1.3, но на один пункт раньше, на транспортном уровне:

TCP представляет собой основанный на соединениях (connection-oriented) транспортный сервис с гарантированной доставкой пакетов, обеспечивающий надежную доставку с сохранением порядка пакетов и управлением потоком данных.Протокол UDP не использует соединений (connectionless) и передает данные в виде дейтаграмм (datagram) без гарантии доставки.
Этот же абзац в английской версии выглядит так:

TCP is a reliable connection-oriented transport service that provides end-to-end reliability, resequencing, and flow control. UDP is a connectionless ("datagram") transport service.
Уважаемый Drop-bear и здравая логика буквально переводят это так:

TCP это надежная модель обмена данными от точки к точке с повторным упорядочиванием и управлением. UDP это модель обмена данными без установки соединения (дейтаграммами).
Заметьте, никаких гарантий.

Второе упоминание (про настройку параметров и их загрузку я опустил) мы встречаем в разделе 4.2.1 (Протокол управления передачей TCP - Введение):

Протокол управления передачей - TCP (Transmission Control Protocol) [TCP:1] представляет собой транспортный протокол стека Internet для работы с виртуальными соединениями. TCP обеспечивает гарантированную доставку с сохранением порядка для полнодуплексных потоков данных (октеты или байты).Протокол TCP используется теми приложениями, которым нужен ориентированный на соединения транспортный сервис с гарантией доставки (например, электронная почта SMTP, передача файлов по протоколу FTP, служба виртуальных терминалов Telnet); требования к таким протоколам прикладного уровня описаны в работе [INTRO:1].

Английский текст:

The Transmission Control Protocol TCP [TCP:1] is the primary virtual-circuit transport protocol for the Internet suite. TCP provides reliable, in-sequence delivery of a full-duplex stream of octets (8-bit bytes). TCP is used by those applications needing reliable, connection-oriented transport service, e.g., mail (SMTP), file transfer (FTP), and virtual terminal service (Telnet); requirements for these application-layer protocols are described in [INTRO:1].

Который можно было бы перевести как (опять спасибо John-1123 и Drop-bear):

Transmission Control Protocol TCP [TCP: 1] является основным виртуальным протоколом транспортной схемы для сети Интернет. TCP обеспечивает надежную, последовательную полнодуплексную доставку потока октетов (8-битный байт). TCP используется приложениями, нуждающимися в надежных способах доставки, ориентированных на соединения между клиентами, например, электронной почтой (SMTP), при передаче файлов (FTP), службы виртуального терминала (Telnet); требования к этим протоколам прикладного уровня описаны в [INTRO:1].
Снова никаких гарантий.

Можно предположить зачем же переводчик добавил эти мнимые гарантии. Возможно, он хотел подчеркнуть отличие TCP от UDP (а как следствие и от IP), а может решил обобщить слова "надежность", "контроль" и другие хорошие (и надежные) слова  в хорошее (и надежное) слово "гарантии".

"И что из этого?" - спросите вы.

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

А из этого следует:

Этап третий: практический.

Если предыдущий этап не убедил вас в том, что TCP все-таки не гарантирует доставки, то давайте проведем эксперимент:
Откройте любое приложение использующее TCP и начните обмен данными (скачивание музыки, получение почты подойдет). TCP гарантирует доставку? Похоже, что да? А теперь вытащите кабель подключения к сети, выключите модем и отключите WiFi (или что у вас там?) Ну, как? Гарантии TCP все еще в силе? =)

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

Т.е. просто написать TCPSocket.Send(*data); и ожидать, что все будет хорошо, строить дальнейший код исходя из посылки о том, что есть "гарантия доставки" в корне не верно.

Представляете, если бы для осуществления ремонта линии электропередач вы бы послали команду "отключить подачу ста тысяч вольт" по TCP и думая о гарантированной доставке сразу полезли бы на столб? Есть среди оставшихся хоть один, кто бы рискнул?

Друзья, читайте RFC в оригинале. Это действительно хороший совет.
(Да, перестаньте плеваться те, кто УЖЕ читают RFC в оригинале, я и сам знаю, что оно сложно переваривается и не менее сложно усваивается. Тем не менее это RFC)

Эпилог: правильные гарантии.

Что же на самом деле гарантирует протокол TCP? Об этом очень хорошо сказано в статье википедии о TCP/IP:
TCP — «гарантированный» транспортный механизм с предварительным установлением соединения, предоставляющий приложению надёжный поток данных, дающий уверенность в безошибочности получаемых данных, перезапрашивающий данные в случае потери и устраняющий дублирование данных. TCP позволяет регулировать нагрузку на сеть, а также уменьшать время ожидания данных при передаче на большие расстояния. Более того, TCP гарантирует, что полученные данные были отправлены точно в такой же последовательности. В этом его главное отличие от UDP.
Слово "гарантированный" (вначале) забрано  в кавычки и все остальное определение на редкость точно и лаконично.

И особенно вкусен конец абзаца, не удержусь и повторю его еще раз:

Более того, TCP гарантирует, что полученные данные были отправлены точно в такой же последовательности. В этом его главное отличие от UDP.

Вот это - правильные гарантии.


Спасибо.

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

Всем счастливо, а умному студенту привет и удачно делать свои снежинки.