Сисадминские байки
Работа сетей достаточно сложная штука. Хотя бы потому, как IP протокол
сам по себе асинхронен. Т.е. посылающая сторона должна ждать подтверждение
от принимающей стороны. Есть конечно, еще и UDP протокол, который подтверждений
не требует. Этим протоколом общаются между собой сервера для обмена информацией
по DNS. Ну, про UDP позже, а вот насчет IP - подробнее:
Разберем простой пример: у вас модем на 33600 (до провайдера),
и у провайдера канал "наружу", допустим, 2Мб. Вы в настоящий момент вытягиваете
тяжелый файл с сервера, находящимся где-то далеко. Скорость download'а
в идеале будет примерно 3.5кб/с (сжатого файла). Т.е. ваша машина
будет получать от модема 3.5 кила в секунду. Но вот с "того" сервера, откуда
производится download - с какой скоростью будут уходить пакеты? И как вообще,
_ваши_ 33600 умещаются в провайдерском канале 2Мб? Может это как-то ограничено?
Важно представить себе работу протокола, чтобы немного разобраться
с этими "простыми" вопросами. Наверное, не стоит представлять себе "толстый"
канал провайдера, как содержащий в себе кучу маленьких подканальчиков на
33600, 14400 и т.д. по числу пользователей. Скорее, это будет просто совокупность
хождения всех пакетов туда-сюда.
Хм... вообще, я эту прелюдию написал, чтоб немного самому раскачаться.
Тут вот какой момент: если вы допустим, "сказали" далекому серверу подать
вам вооон тот файл, и он начал его добросовестно вам передавать, и совсем
не знал, что после 2-3 минут передачи у вас отрубят свет, произодет крах
вашей системы или еще какая бяка, которая временно или надолго отрубит
вас от сети. Куда денутся пакеты с информацией? И вообще, как серверу узнать,
что вы все еще хотите принимать файл или уже нажали "Cancel", потому как
поняли что энное количество мегабайт со скоростью 4б/с вам еще долго не
вытянуть... И почему при закачке файла (к вам) по ftp скорость сначала
растет, а потом может и упасть? Почему она вообще, сначала растет?
Попробую ответить так: потому как удаленный сервер не знает, на какой
скорости вы подключены и начинает слать вам пакеты, скажем по 700 байт,
а после того, как придет подтверждение, он уже решает, повысить размер
пакета или нет. После того, как ваша система приняла пакет с информацией,
она должна отослать подтверждение о приеме тому серверу, откуда она этот
пакет получила. Это и есть асинхронная передача данных.
Но существует еще и такое понятие, как время жизни пакета - TTL (time
to live) - оно устанавливается в каждом пакете для того, чтобы не засорять
сети "умершими" данными. Причем, когда такой пакет находясь даже уже в
пути, в маршрутизаторе, исчерпает свое время жизни, маршрутизатор его преспокойно
грохнет. Посему, если вы приняли пакет, отослали на него подтверждение
и "тот" сервер послал вам следующий, а вы в это время как раз скоропостижно
"рухнули", то пакет умрет, а "тот" сервер, не получив ожидаемого подтверждения,
успешно закроет сессию. Умер, так умер. Но только попеременно передавать-принимать
пакеты с подтверждениями немного неинтересно. Гораздо красивее запустить
какую-то кучку пакетов, а потом получать на них подтверждения. Так и образуется
стек FIFO (первым вошел-первым вышел) IP пакетов. Которые гуськом торопятся
попасть к вам в тачку. Опять-таки, торопиться они могут перегоняя друг
друга, фрагментируясь и дефрагментируясь по дороге, а нормальное фифо собирается
tcp логикой уже из приемных буферов. И, кстати, нюкалка teardrop основана
на неправильном задании размеров фрагментов пакетов, отчего у сборщика
крыша съезжает напрочь и ваша тачка честно виснет.
В TCP есть такое понятие, как "окно". Это значит, что передающая сторона
передает несколько пакетов, не дожидаясь подтверждения на первые пакеты.
Т.е. с передающей стороны уходит сразу достаточно большой кусок данных,
которые оседают в различных буферах пока не протиснутся в клиентские 33600.
Для вышеупомянутого "окна" существует механизм регулирования в зависимости
от скорости в канале передачи.
Очередь большой не делается, а делается она исходя из некоей статистики,
собранной за предыдущее время - так сервер пытается понять, с какой скоростью
и какого размера пакеты вы успеваете прокачивать. А вот если попадется
такая ситуация, что половину из пакетов стоящих в очереди вы приняли, а
на следующем пакете получился облом (ну не принялся он...). Что
произойдет с остальными пакетами стоящими в очереди? Они благополучно умрут,
т.к. на сервер от вас пойдет команда перепослать пакеты с номера такого-то,
начиная с того места, где произошел обрыв, а эти пакеты бросят умирать.
Подводя итог, можно сказать, что скорость выкачки зависит: от того,
насколько быстро приходят пакеты к вам, от того, насколько быстро доходят
от вас подтверждения на них другому серверу. Следовательно, если на канале
"висит" много пользователей и особенно таких, у которых скорость выше чем
у вас, то их пакеты будут ходить чаще (у них ведь время ответа
будет меньше), и следовательно, ваши пакеты могут не успевать проскакивать
между потоком их пакетов и будут тормоза. Что и можно наблюдать на загруженных
серверах или каналах. Пробки как раз и возникают таким образом - стоит
пакетам скопиться где-нибудь и - все. Особенно, если из-за этого маршрутизатором
будет сброшен какой-нибудь пакет соединения, тогда приемник (ваша тачка)
подождет еще некоторое время (таймаут) в надежде дождаться отброшенного
пакета, и только после этого пошлет запрос передатчику на перепосылку утерянного
пакета.
Продолжение еще будет...
|