Теперь рассмотрим часть кода, описывающую клиента. Чтобы понять, как работает программа, необходимо вначале разобраться, как она запускается. Если она называется client , ее типичный вызов будет выглядеть так:
client flits.csvu.nl /usr/tom/filename >f
Этот вызов сработает только в том случае, если сервер расположен по адресу flits. cs.vu.nl, файл/usr/tom/filename существует и у сервера есть доступ по чтению для этого файла. Если вызов произведен успешно, файл передается по Интернету и записывается на местоf , после чего клиентская программа заканчивает свою работу. Поскольку серверная программа продолжает работать, клиент может быть запущен снова с новыми запросами на получение файлов.
Клиентская программа начинается с подключения файлов и объявлений. Работа начинается с проверки корректности числа аргументов (argc = 3 означает, что в строке запуска содержалось имя программы и два аргумента). Обратите внимание на то, чтоargv[1] содержит имя сервера (например, flits.cs.vu.nl) и переводится в IP-адрес с помощьюgethostbyname . Для поиска имени функция использует DNS. Мы будем изучать технологию DNS в главе 7.
Затем создается и инициализируется сокет, после чего клиент пытается установить TCP-соединение с сервером посредствомconnect . Если сервер включен, работает на указанной машине, соединен сSERVER_PORT и либо простаивает, либо имеет достаточно места в очередиlisten (очереди ожидания), то соединение с клиентом будет рано или поздно установлено. По данному соединению клиент передает имя файла, записывая его в сокет. Количество отправленных байтов на единицу превышает требуемое для передачи имени, поскольку нужен еще нулевой байт-ограничитель, с помощью которого сервер может понять, где кончается имя файла.
Теперь клиентская программа входит в цикл, читает файл блок за блоком из сокета и копирует на стандартное устройство вывода. По окончании этого процесса она просто завершается.
Процедураfatal выводит сообщение об ошибке и завершается. Серверу также требуется эта процедура, и она пропущена в листинге только из соображений экономии места. Поскольку программы клиента и сервера компилируются отдельно и в обычной ситуации запускаются на разных машинах, код процедурыfatal не может быть разделяемым.
Эти две программы (как и другие материалы, связанные с этой книгой) можно найти на веб-сайте книги по адресу http://www.prenhall.com/tanenbaum.
Кстати говоря, такой сервер построен далеко не по последнему слову техники. Осуществляемая проверка ошибок минимальна, а сообщения об ошибках реализованы весьма посредственно. Система будет обладать низкой производительностью, поскольку все запросы обрабатываются только последовательно (используется один поток запросов). Понятно, что ни о какой защите информации здесь говорить не приходится, а применение аскетичных системных вызовов UNIX — это не лучшее решение для достижения независимости от платформы. Делаются некоторые некорректные с технической точки зрения предположения. Например, о том, что имя файла всегда поместится в буфер и будет передано без ошибок. Несмотря на эти недостатки, с помо
щью данной программы можно организовать полноценный работающий файл-сервер для Интернета. Более подробную информацию можно найти в (Donahoo и Calvert, 2008, 2009).
6.2. Элементы транспортных протоколов
Транспортные услуги реализуются транспортным протоколом, используемым между двумя транспортными подсистемами. В некоторых отношениях транспортные протоколы напоминают протоколы канального уровня, подробно изучавшиеся в главе 3. И те и другие протоколы, наряду с другими вопросами, занимаются обработкой ошибок, управлением очередями и потоками.
Однако у них имеется и много существенных различий, обусловленных различиями условий, в которых работают эти протоколы, как показано на рис. 6.4. На канальном уровне два маршрутизатора общаются напрямую по физическому каналу (проводному или беспроводному), тогда как на транспортном уровне физический канал заменен целой сетью. Это отличие оказывает важное влияние на протоколы.

Рис. 6.4. Окружение: а — канального уровня; б — транспортного уровня
Во-первых, при двухточечном соединении по проводу или оптоволоконной линии маршрутизатору обычно не требуется указывать, с каким маршрутизатором он хочет поговорить, — каждая выходная линия ведет к определенному маршрутизатору. На транспортном уровне требуется явно указывать адрес получателя.
Читать дальше
Конец ознакомительного отрывка
Купить книгу