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

Видно, что команда curl начинает работу с отправки запроса GET серверу (как вы это делали с помощью команды telnet), за которым следует дополнительная информация для сервера и пустая строка. Далее сервер отправляет ответ, первый с собственным заголовком, который выделен здесь жирным шрифтом:

<= Recv header, 17 bytes (0x11)

0000: HTTP/1.1 200 OK

<= Recv header, 16 bytes (0x10)

0000: Server: Apache

<= Recv header, 42 bytes (0x2a)

0000: X-Powered-By: PHP/5.3.10-1ubuntu3.9+wmf1

— snip

Во многом подобно предыдущему выводу, здесь строки <= являются отладочными, а числа 0000:, с которых они начинаются, сообщают вам смещения.

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

<= Recv header, 55 bytes (0x37)

0000: X–Cache: cp1055 hit (16), cp1054 frontend hit (22384)

<= Recv header, 2 bytes (0x2)

0000:

<= Recv data, 877 bytes (0x36d)

0000: 008000

0008: ...

— snip

Этот вывод иллюстрирует также важное свойство прикладного уровня. Даже если отладочный вывод содержит Recv header и Recv data, подразумевая за ними два различных типа сообщений от сервера, нет никаких различий ни в том, как команда curl общается с операционной системой для извлечения этих сообщений, ни в том, как операционная система обращается с ними, ни в том, как сеть обрабатывает лежащие в их основе пакеты. Различие содержится полностью внутри приложения curl в пространстве пользователя. Команда curl знает о том, что она получает заголовки, пока ей не встретится пустая строка (двухбайтный фрагмент в середине), которая сигнализирует об окончании HTTP-заголовков, тогда команда интерпретирует все, что последует далее, как запрашиваемый документ.

Это же верно и для сервера, отправляющего данные. При отправке ответа сервер не делает различий между заголовком и данными документа, отправленными операционной системе; различия появляются внутри серверной программы в пространстве пользователя.

10.2. Сетевые серверы

Большинство сетевых серверов подобно другим демонам системы, таким как cron, за исключением того, что они взаимодействуют с сетевыми портами. В самом деле, вспомните демон syslogd, описанный в главе 7: он принимает пакеты UDP в сетевом порте 514, когда запущен с параметром — r.

Есть несколько других распространенных сетевых серверов, которые вы можете найти в своей системе:

• httpd, apache, apache2 — веб-серверы;

• sshd — демон защищенной оболочки (см. раздел 10.3);

• postfix, qmail, sendmail — почтовые серверы;

• cupsd — сервер печати;

• nfsd, mountd — демоны сетевой файловой системы (для совместного использования файлов);

• smbd, nmbd — демоны совместного использования файлов Windows (см. главу 12);

• rpcbind — демон удаленного вызова процедуры (RPC, Remote Procedure Call) для службы зеркала портов.

Общим свойством большинства сетевых серверов является то, что они обычно действуют в виде нескольких процессов. Хотя бы один из процессов прослушивает сетевой порт, и когда поступает новое входящее соединение, прослушивающий процесс использует команду fork(), чтобы создать новый дочерний процесс, который становится ответственным за новое соединение. Процесс-потомок, или исполнитель, завершает работу при закрытии соединения. Тем временем исходный процесс продолжает прослушивание сетевого порта. Этот процесс позволяет серверу с легкостью справляться с множеством подключений, не создавая сложностей.

Однако имеются некоторые исключения из этой модели. Вызов команды fork() добавляет системе дополнительную работу. Для сравнения: такие высокопроизводительные TCP-серверы, как веб-сервер Apache, могут во время запуска создать несколько процессов-исполнителей, чтобы они всегда были наготове для обработки соединений. Серверы, которые принимают UDP-пакеты, просто получают данные и реагируют на них. У них нет соединений, которые надо прослушивать.

10.3. Защищенная оболочка (SSH)

Перейти на страницу:

Похожие книги