UNИX, осень 2008, 08 лекция (от 19 ноября)

Материал из eSyr's wiki.

Версия от 18:14, 19 ноября 2008; 92.36.39.233 (Обсуждение)
(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)
Перейти к: навигация, поиск

Лектор делится открытием, не имеющим напрямую отношения к теме лекции. Вышел новый дистрибутив AltLinux Desktop 4.1. Были нарекания к дизайнеру (трава, поврежденная тлей). Полоски с градиентом можно генерировать автоматически с помощью программы (штук 50) и выбрать лучший. С помощью какой программы можно генерировать фон разных размеров? ImageMagick растровый. Можно сгенерировать картинку и ресайзить. Не умеет рисовать фигуры. Было бы неплохо сделать в векторном режиме, а затем генерировать нужного размера. Выбираешь количество, тип градиента. Было предположение о GLE. GLE — язык написания простейших программ, рисующих картинки. Что-то вроде PostScript на человеческом языке. График синуса на координатной оси с подписями генерируется 4 строками. Все же он заточен под математическую работу. Интересно, чтобы были абстрактные фигуры.

Два расширения: ASCII svg, ASCII math. Позволяют публиковать на сайте картинки и математику. Первое — текстовое описание картинки. Второе — облегченный вариант латеха. Вставляем, включаем небольшой JavaScript, на экране — красивый результат. SVG хорошо работает в Firefox, для IE нужно что-то ставить.

Существует ли более-менее разумный компилятор простого svg?

Закрываем тему.

Открываем тему транспортного уровня стека протоколов TCP/IP. За последнее тысячелетие сведения сильно устарели. Если использовать литературу прошлого тысячелетия, можно знать не все.

Теория. Что такое транспортный уровень? Такой уровень, когда мы хотим забыть о проблемах доставки. Под ним лежит сетевой уровень с проблемами идентификации и доставки пакета (маршрутизация). Маршрутизации две — IP и доступность больших систем. OSPF — протокол маршрутизации высокого уровня. Согласно правилу независимости уровней мы забываем о маршруте и говорим о потоке данных. Транспортный протокол оперирует потоками данных.

Во-первых, обеспечиваем надежность и целостность. Речь идет о том, что мы хотим забыть о том, что Интернет — штука ненадежная. Пакеты могут теряться, самозарождаться, портиться, множиться, последовательность пакетов может меняться местами. Мы хотим об этом не знать. На следующем уровне (прикладном) мы будем общаться либо с ненадежными данными, либо мы обеспечиваем надежность на транспортном уровне. Гарантируем, что данные не испортились и пришли все. Другая задача состоит в том, чтобы работать с потоками данных, а не только с данными любого вида, которые отправляются и получаются. Идея в том, что когда несколько сеансов передачи данных, с точки зрения IP это одни и те же пакеты, с одним отправителем и получателем. Различные сеансы, потоки данных должны различаться между собой. Задача — управление потоками. Не только различать, но и управлять качеством потока.

Если есть очень мощный компьютер, подключенный к скоростной сети, а получатель — слабый компьютер с медленным подключением, может получиться следующая ситуация. Отправитель отправляет в большом количестве, отправил первый гигабайт, а получатель получил первые 10 килобайт. Хорошо иметь информацию о передаче. Может быть высокий процент потерь. Если плохое качество среды, нужно уменьшать размер пакета. Чем меньше пакет, тем меньше шансов, что он попортится.

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

Важным фактором является то, что начиная с интерфейсного уровня сети — сети без гарантированного времени передачи данных. Один из способов реализации такой: мы для начала потребуем от нашего получателя, чтобы он нам ответил. Мы посылаем пакет на деревню дедушке, а деревни нет, или деревня есть, а дедушки нет. Когда посылаем пакет, нужно убедиться, что получатель существует. Установка соединения. Передача с установлением соединения и без него. Первое в реальном времени, второе — нет. Перед передачей данных убеждаемся, что получатель существует. Что это гарантирует? То, что мы передаем, может куда-то попасть. Если адресат не ответил, с большой вероятностью то, что мы отправляем, никуда не попадет. Если же ответил, скорее всего, попадет.

В ответе можно передавать дополнительные вещи. Уже возникает некая двунаправленность. Посылаем запрос и отвечаем, что соединение установлено. Один передает, и другой. Мы можем эксплуатировать это и сделать подтверждение. Получатель сообщает, что данные приняты и нормально, или приняты, но не такие, или через некоторое время приходит ответ, что данные не получены. Или адресат ничего не сообщает, или не принял, или то, что ответил, не пришло, или еще что-то случилось.

Каждая транзакция пакета сопровождается подтверждением получения, причем корректного. Отслеживание состояния канала. Внутри каждого пакета будет контрольная сумма, ее будут проверять.

Упорядочивание. Мы должны перенумеровать все пакеты данных. Отправитель нумерует, а получатель должен уметь отслеживать порядок, например, он получил не второй, а третий пакет. Должен сообщить отправителю: «Чувак, гони второй пакет».

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

Контрольная сумма (избыточная информация).

Отслеживание состояния канала (балансировка канала). Балансировка канала — алгоритм скользящего окна, медленный старт. Прежде чем скажем о реализованности, давайте посмотрим, какие из инструментов пригодны не всегда при передаче данных из одного места в другое.

Вычисление контрольной суммы никогда не вредно, по мнению лектора. Разве что совсем не хватает вычислительной мощности. Широковещательная трансляция — пример. Одними подтверждениями можно привести сервер в глубокое изумление. При подтверждениях с повторной передачей изумление еще более глубокое. Установление соединения с каждым из абонентов может сделать передачу невозможной — кто-то будет выключен. Если не требуется упорядочивать все данные от начала до конца, то упорядочивание может быть лишней штукой. С упорядочиванием не совсем ясно. Балансировка тоже вещь туманная. Балансировка нагрузки даже если мы хотим делать широковещание — в общем-то, вещь полезная.

В TCP все 5 пунктов (соединение, подтверждение, упорядочивание, контрольная сумма, балансировка) реализованы, в UDP — только контрольная сумма, да и то можно отключать. Что касается UDP, все достаточно понятно. Единственное ограничение — чтобы пакет не рассыпался по дороге. Получит или не получит адресат сообщение — неизвестно. Прежде чем перейти к рассмотрению TCP, решим частную задачу. На уровне разделения потоков потоки должны иметь разные идентификаторы. Помимо IP получателя и отправителя должен существовать идентификатор потока.

По причинам отчасти историческим, отчасти того, как это реализовано, их три. В UDP — cond. Аппаратная абстракция — есть процессор, устройства ввода-вывода, каждое устройство — к одному порту. Когда отправляем датаграмму с компьютера, есть порт отправителя и порт получателя. Эта четвертка (два IP, два порта) идентифицирует поток данных. Есть всякие хитрости, с этим связанные, например, IP может быть не равен тому, который используется. Главное, что четвертка уникально идентифицирует поток данных.

В случае протокола TCP, обеспечивающего все, ситуация более сложная. У лектора была мысль, что в UDP порт отправителя лишний. Отправление обратно можно сделать на прикладном уровне, т.к. ответ не обязателен. В TCP же соединение двунаправленное соединение между отправителем и получателем.

Уже на этапе установления соединения получатель отвечает «Да, я жив». В ответе должен быть указан порт отправителя. В течение всего сеанса четверка идентифицирует поток данных.

Наша задача не только различать потоки, но и упорядочивать. На уровне TCP есть SeqN1 (Sequence Number), SeqN2. Универсальный способ контролировать пропажу или размножение пакетов. Номер в последовательности. Одновременно и номер пакета, и размер пакета. Алгоритм простой: когда отправитель хочет установить соединение, он посылает получателю запрос (SYN), генерирует случайный SeqN1. Получатель отвечает SYN, ACK. Отправитель подтверждает (ACK), что с ним можно связываться и передавать данные. Данные размера S, передается SeqN1 + S. Дальше обычный обмен пакетами.

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

Двустороннесть позволяет подтверждать. Возможны различные ошибки, требования повторной передачи. В алгоритме не предусмотрено ничего для балансировки канала. А она была бы не плоха, потому что пакет долго ходит по Интернету, размер одновременно передаваемого куска был как можно больше. Пока это не перегружает получателя и пакет нормально идет по сети.

Задачи балансировки — приноравливаться к состоянию канала и к состоянию получателя. Поскольку передача всегда синхронная, большую роль играет размер передаваемого пакета. Если увеличивать размер пакета, увеличивается вероятность передачи. Чем качественнее канал, тем лучше.

Примем на веру следующее утверждение — в TCP есть возможность не дожидаться подтверждения на пакет и отправлять их без подтверждения пачкой. Количество пакетов пачкой зависит от размера окна. Размер окна вначале условно равен 1 пакету. Получатель говорит, можно 100. Отправитель отправляет 2, потом 4, пока получатель не скажет «Хватит», или пока не пойдут ошибки. Определение окна — дело ОС, точнее, подсистемы TCP/IP. Какой реально размер окна, готового принять. Определяется из многих параметров.

Начинается с одного пакета. Всякий раз говорим, какой размер окна. Отправитель каждый раз должен проверять, не забил ли он окно получателя. У него есть информация о окне получателя, и о том, сколько пакетов в окне получатель уже подтвердил. Если пришли подтверждения, окно сдвинулось. Или из 100 пакетов ни одного подтверждения не пришло, сколько ни передали, они пока висят. Вычисляем разницу между подтвержденными пакетами и размере окна.

Идея скользящего окна в следующем. Есть буфер на N пакетов. Обе стороны принимающие, обе стороны отправители. Кто первый начал соединение, и кто ответил. На стороне получателя (половина соединения) есть окно в N пакетов. Туда приходят пакеты. Пришел первый пакет. Окно сдвигается. Допустим, пришел второй пакет. Окно не сдвигается. Поскольку пришел второй пакет, мы подтверждаем, но по-другому. Пришел пакет, в окно влезает, но он не первый, давай первый. Если отправитель получил подтверждение, что окно отъехало, можно отправлять дальше. Если получил подтверждение не первого пакета, нужно перепосылать. В случае, если приняты все подтверждения, кроме первого, первый просто пропал. Его нужно послать еще раз. Окно не сдвинется, пока первый пакет не придет. Окно может забиться, и по приходу первого сдвинется сразу далеко.

Подтверждения — тоже пакеты, они могут пропадать. Допустим, одно подтверждение пропало (2 пакет). Ничего не произойдет, если придет подтверждение 3 пакета. Будем считать, что Интернет — штука ненадежная. Реально получить подтверждение 20 пакета, и до этого все в порядке. Не обязательно получать подтверждение всех пакетов. Если первый пакет не получен, подтверждение будет другого вида.

Главное — получить подтверждение, отвечающее за всех. В английской Википедии есть демонстрация. Можно устанавливать процент потерянных пакетов. Таймаут. Лектор рекомендует всем погонять эту флэшку.

Что еще можно придумать к скользящему окну? Две дополнительные заморочки, но они не реализованы в TCP. Одна — Go Back — сдвигаем окно обратно. Сложность в том, что мы можем предсказать, что придут пакеты и сдвинуть окно. В некоторых случаях позволяет улучшить качество. Вторая штука — Selective Reject — мы говорим, какой конкретно пакет нужно перепослать, и перепосылаем именно его. Это все либо не реализовано, либо бессмысленно в TCP.

Немного разговора о том, когда применять TCP, когда UDP. TCP — синхронный протокол. Если рисовать графики, большую роль играет скорость передачи. В случае TCP мы имеем систему «пакет-подтверждение». В случае UDP можно передавать и передавать. Скорость может быть больше. Но возникают проблемы при происхождении ошибок.

В случае, если произошла ошибка на UDP, с этим разбирается приложение. Сколько приложение будет разбираться, неизвестно. В конце концов, оно пошлет на прикладном уровне пакет серверу «У меня что-то со вторым пакетом». В случае, если цена ошибки высока, скорость передачи по TCP с возникающими ошибками быстрее. Обычно обмен данными идет по TCP.

Можно запрограммировать TCP на уровне приложения, а потом плюнуть и воспользоваться TCP.

Реально UDP используется, когда весь обмен умещается в одной датаграмме. Пример — DNS-запрос. Еще при широковещательной передаче. Может быть так, что UDP лучше, а редкие ошибки проще обрабатывать на прикладном уровне. Еще пример — NFS на высоконадежной сети.

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

Есть 4 протокола, найденные автором в Википедии. Реализация всего этого имеется, использоваться начнется, когда у всех будет IPv6. Нормальный QoS можно сделать только там, в IPv4 нельзя, там только один байт.

RSVP (Resource Reservation Protocol). Протокол управляющий, предназначенный, чтобы разгрести место для последующей передачи данных в высоким QoS. Для передачи видео должно быть место в памяти для этих пакетов. Естественно, TCP обработает как надо, UDP не обработает. Прежде, чем прокладывать дорогу для видеопотока, неплохо бы сообщить по дороге, что сейчас пойдет видеотрафик. Это управляющий протокол, но говорит о потоках. В чем хорошая идея? Если наше устройство поддерживает, можно надеяться, что проблемы возникнут только при сбоях аппаратуры, а ресурсы зарезервированы (или маршрутизатор скажет, что ресурсов не хватает).

Протокол ECN. Как TCP справляется с ситуацией, когда отправитель отправляет слишком много? Просто выбрасывает. Пока не докатится окошко, отправитель будет слать и слать. Мы пытаемся предотвратить перегрузку сети пакетами. Нужно сказать отправителю, чтобы он сокращал поток. Принимая во внимание особенности протокола ECN, можно разработать еще пару протоколов, которые могут как-то взаимодействовать.

Есть протокол DCCP (Datagram Conversion Control Protocol). Происходит управление (контроль за переполнением потока датаграмм). Что-то более хитрое, чем UDP. Должна быть информация о том, что ЕСN поддерживается. Голый UDP не может воспользоваться ECN. Никакого упорядочения в случае DCCP нет, есть понятие потока как такового. Чтобы регулировать напряженность потока, используется ECN. Контроль за переполнением.

Более развесистый протокол — SCTP. Не гибрид TCP и UDP. Работает с потоком байт. Не все программы хотят, чтобы им передавали поток байт от начала до конца.

Запрос на веб-страницу. Неважно, когда скачаются картинки, первыми или вторыми. Картинки могут скачиваться в любом порядке. Картинка не может быть одним пакетом. Внутри сообщения порядок важен. Внутри одного соединения может быть несколько потоков данных (внутри одного потока).

Все это было подготовлено для IPv6. Эта штука более гибкая. Все эти описанные вещи давно есть в RFC, реализованы в большинстве сетевых ядер. Проблема в том, что не все железяки умеют.

Мы можем переходить к прикладному уровню.

Личные инструменты
Разделы