Обратите внимание на то, что в нашем примере сервис ftp предоставляется внешней программой wu.ftpd. Если в вашей системе выполняется демон inetd, вы можете изменить набор предоставляемых сервисов, отредактировав файл /etc/inetd.conf (знак # в начале строки указывает на то, что это строка комментария) и перезапустив процесс inetd. Сделать это можно, отправив сигнал отбоя (hang-up) с помощью команды kill
killall:# killall -HUP inetd
Параметры сокета
Существует много параметров, которые можно применять для управления поведением соединений на базе сокетов — слишком много для подробного описания в этой главе. Для манипулирования параметрами используют функцию setsockopt
#include
int setsockopt(int socket, int level, int option_name,
const void *option value, size_t option len);
Задавать параметры можно на разных уровнях иерархии протоколов. Для установки параметров на уровне сокета вы должны задать level
SOL_SOCKET. Для задания параметров на более низком уровне протоколов (TCP, UDP и т.д.) приравняйте параметр level номеру протокола (полученному либо из заголовочного файла netinet/in.h, либо из функции getprotobyname).В аргументе option_name
option_value содержит произвольное значение длиной option_len байтов, передаваемое без изменений обработчику низкоуровневого протокола.Параметры уровня сокета определены в заголовочном файле sys/socket.h и включают приведенные в табл. 15.4 значения.
| Параметр | Описание |
|---|---|
SO_DEBUG | Включает отладочную информацию |
SO_KEEPALIVE | Сохраняет активными соединения при периодических передачах |
SO_LINGER | Завершает передачу перед закрытием |
Параметры SO_DEBUG
SO_KEEPALIVE принимают целое значение option_value для установки или включения (1) и сброса или выключения (0). Для параметра SO_LINGER нужна структура типа linger, определенная в файле sys/socket.h и задающая состояние параметра и величину интервала задержки.Функция setsockopt
Множественные клиенты
До сих пор в этой главе вы видели, как применяются сокеты для реализации клиент-серверных систем, как локальных, так действующих, в сети. После установки соединения на базе сокетов они ведут себя как низкоуровневые открытые файловые дескрипторы и во многом как двунаправленные каналы.
Теперь необходимо рассмотреть случай множественных клиентов, одновременно подключающихся к серверу. Вы видели, что, когда серверная программа принимает от клиента запрос на соединение, создается новый сокет, а исходный сокет, ожидающий запросы на соединение, остается доступен для последующих запросов. Если сервер не сможет немедленно принять поступившие позже запросы на соединения, они сохранятся в очереди ожидания.
Тот факт, что исходный сокет все еще доступен, и что сокеты ведут себя как файловые дескрипторы, дает нам метод одновременного обслуживания многих клиентов. Если сервер вызовет функцию fork
Поскольку вы создаете дочерние процессы, но не ждете их завершения, следует сделать так, чтобы сервер игнорировал сигналы SIGCHLD
1. Программа server4.c начинается так же, как последний рассмотренный сервер с важным добавлением директивы include
#include
#include
#include
#include
#include
#include
int main() {
int server_sockfd, client_sockfd;
int server_len, client_len;
struct sockaddr_in server_address;
struct sockaddr_in client_address;
server_sockfd = socket(AF_INET, SOCK_STREAM, 0);
server_address.sin_family = AF_INET;