Здесь первая строка представляет отладочный вывод команды 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
—
Во многом подобно предыдущему выводу, здесь строки <= являются отладочными, а числа 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: ...
—
Этот вывод иллюстрирует также важное свойство прикладного уровня. Даже если отладочный вывод содержит 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)