Страница 37 из 399
Глава 4
Элементарные сокеты TCP
4.1. Введение
В этой главе описываются элементарные функции сокетов, необходимые для написания полностью работоспособного клиента и сервера TCP. Сначала мы опишем все элементарные функции сокетов, которые будем использовать, а затем в следующей главе создадим клиент и сервер. С этими приложениями мы будем работать на протяжении всей книги, постоянно их совершенствуя (см. табл. 1.3 и 1.4).
Мы также опишем параллельные (concurrent) серверы — типичную технологию Unix для обеспечения параллельной обработки множества клиентов одним сервером. Подключение очередного клиента заставляет сервер выполнить функцию fork, порождающую новый серверный процесс для обслуживания этого клиента. Здесь применительно к использованию функции fork мы будем рассматривать модель «каждому клиенту — один процесс», а в главе 26 при обсуждении программных потоков расскажем о модели «каждому клиенту — один поток».
На рис. 4.1 представлен типичный сценарий взаимодействия, происходящего между клиентом и сервером. Сначала запускается сервер, затем, спустя некоторое время, запускается клиент, который соединяется с сервером. Предполагается, что клиент посылает серверу запрос, сервер этот запрос обрабатывает и посылает клиенту ответ. Так продолжается, пока клиентская сторона не закроет соединение, посылая при этом серверу признак конца файла. Затем сервер закрывает свой конец соединения и либо завершает работу, либо ждет подключения нового клиента.
Рис. 4.1. Функции сокетов для элементарного клиент-серверного соединения TCP
4.2. Функция socket
Чтобы обеспечить сетевой ввод-вывод, процесс должен начать работу с вызова функции socket, задав тип желаемого протокола (TCP с использованием IPv4, UDP с использованием IPv6, доменный сокет Unix и т.д.).
#include <sys/socket.h>
int socket(int <i>family</i>, int <i>type</i>, int <i>protocol</i>);
<i>Возвращает: неотрицательный дескриптор, если функция выполнена успешно, -1 в случае ошибки</i>
Константа family задает семейство протоколов. Ее возможные значения приведены в табл. 4.1. Часто этот параметр функции socket называют «областью» или «доменом» (domain), а не семейством. Значения константы type (тип) перечислены в табл. 4.2. Аргумент protocol должен быть установлен в соответствии с используемым протоколом (табл. 4.3) или должен быть равен нулю для выбора протокола, по умолчанию соответствующего заданному семейству и типу.
Таблица 4.1. Константы протокола (family) для функции socket