if (connect(socket_fd, &name,
sizeof(struct sockaddr_in)) == -1) {
perror("connect");
return 1;
}
/* получаем содержимое начальной страницы сервера. */
get_home_page(socket_fd);
return 0;
}
Программа извлекает имя Web-сервера из командной строки (имя не является URL-адресом, т.е. в нем отсутствует префикс http://
). Далее вызывается функция gethostbyname()
, которая преобразует имя сервера в числовое представление. После этого программа подключает потоковый (TCP) сокет к порту 80 сервера. Web-серверы общаются по протоколу HTTP (Hypertext Transfer Protocol), поэтому программа посылает HTTP-команду GET, в ответ на которую сервер возвращает текст начальной страницы.
По существующему соглашению Web-серверы ожидают поступления запросов на порт 80. За большинством lntemet-сервисов закреплены стандартные номера портов. Например, защищенные Web-серверы работающие по протоколу SSL. прослушивают порт 443 а почтовые серверы (протокол SMTP) прослушивают порт 25
В Linux связи между именами протоколов/сервисов и номерами портов устанавливаются в файле /etc/services
. В первой колонке файла указано имя протокола или сервисе. Во второй колонке приведен номер порта и тип взаимодействия: tcp
— для сервисов ориентированных на соединения, и udp
— для дейтаграмм.
При реализации собственных сетевых сервисов используйте номере портов, большие чем 1024
Например, чтобы получить начальную страницу с сервера www.codesourcery.com
, введите следующую команду:
% ./socket-inet www.codesourcery.com
content="text/html; charset=iso-8859-1">
...
5.5.7. Пары сокетов
Как было показано выше, функция pipe()
создает два дескриптора для входного и выходного концов канала. Возможности каналов ограничены, так как с файловыми дескрипторами должны работать связанные процессы и данные через канал передаются только в одном направлении. Функция socketpair()
создает два дескриптора для двух связанных сокетов, находящихся на одном компьютере. С помощью этих дескрипторов можно организовать двунаправленное взаимодействие процессов.
Первые три параметра функции socketpair()
такие же, как и в функции socket()
: пространство имен (должно быть PF_LOCAL
), тип взаимодействия и протокол. Последний параметр — это массив из двух целых чисел, куда будут записаны дескрипторы сокетов, подобно функции pipe()
.
Часть II
Секреты Linux
Глава 6
Устройства
Linux, как и большинство операционных систем, взаимодействует с аппаратными устройствами посредством модульных программных компонентов, называемых
В Linux драйверы устройств являются частью ядра и могут подключаться к ядру статически либо по запросу в виде модулей. Драйверы недоступны напрямую пользовательским процессам. Но в Linux имеется особый механизм — специальные файловые объекты, позволяющие процессам взаимодействовать с драйверами, а через них — с аппаратными устройствами. Такие объекты являются частью операционной системы, поэтому программы могут открывать их, читать из них данные и осуществлять запись в них точно так же, как если бы это быта обычные файлы. С помощью низкоуровневых вызовов (описаны в приложении Б, "Низкоуровневый ввод-вывод") или стандартных библиотечных функций ввода-вывода программы могут обмениваться данными с устройствами через файловые объекты
В Linux есть также ряд файловых объектов, предназначенных для доступа к ядру, а не к драйверам устройств. Такие объекты не связаны с аппаратными устройствами. Они реализуют специальные функции, используемые приложениями и системными программами.