Чтение онлайн

на главную - закладки

Жанры

UNIX: разработка сетевых приложений
Шрифт:

Возвращает: неотрицательный дескриптор в случае успешного выполнения функции, -1 в случае ошибки

Аргументы

cliaddr
и
addrlen
используются для возвращения адреса протокола подключившегося процесса (клиента). Аргумент
addrlen
— это аргумент типа «значение-результат» (см. раздел 3.3). Перед вызовом мы присваиваем целому числу, на которое указывает
*addrlen
, размер структуры адреса сокета, на которую указывает аргумент
cliaddr
, и по завершении функции это целое число содержит действительное
число байтов, помещенных ядром в структуру адреса сокета.

Если выполнение функции

accept
прошло успешно, она возвращает новый дескриптор, автоматически созданный ядром. Этот дескриптор используется для обращения к соединению TCP с конкретным клиентом. При описании функции
accept
мы называем ее первый аргумент прослушиваемым сокетом( listening socket) (дескриптор, созданный функцией
socket
и затем используемый в качестве аргумента для функций
bind
и
listen
), а значение, возвращаемое этой функцией, мы называем присоединенным сокетом( connected socket). Сервер обычно создает только один прослушиваемый сокет, который существует в течение всего времени жизни сервера. Затем ядро создает по одному присоединенному сокету для каждого клиентского соединения, принятого с помощью функции
accept
(для которого завершено трехэтапное рукопожатие TCP). Когда сервер заканчивает предоставление сервиса данному клиенту, сокет закрывается.

Эта функция возвращает до трех значений: целое число, которое является либо дескриптором сокета, либо кодом ошибки, а также адрес протокола клиентского процесса (через указатель

cliaddr
) и размер адреса (через указатель
addrlen
). Если нам не нужно, чтобы был возвращен адрес протокола клиента, следует сделать указатели
cliaddr
и
addrlen
пустыми указателями.

В листинге 1.5 показаны эти моменты. Присоединенный сокет закрывается при каждом прохождении цикла, но прослушиваемый сокет остается открытым в течение времени жизни сервера. Мы также видим, что второй и третий аргументы функции

accept
являются пустыми указателями, поскольку нам не нужно идентифицировать клиент.

Пример: аргументы типа «значение-результат»

В листинге 4.2 представлен измененный код из листинга 1.5 (вывод IP-адреса и номера порта клиента), обрабатывающий аргумент типа «значение-результат» функции accept.

Листинг 4.2. Сервер определения времени и даты, сообщающий IP-адрес и номер порта клиента

//intro/daytimetcpsrv1.c

1 #include "unp.h"

2 #include <time.h>

3 int

4 main(int argc, char **argv)

5 {

6 int listenfd, connfd;

7 socklen_t len;

8 struct sockaddr_in servaddr, cliaddr;

9 char buff[MAXLINE];

10 time_t ticks;

11 listenfd = Socket(AF_INET, SOCK_STREAM, 0);

12 bzero(&servaddr, sizeof(servaddr));

13 servaddr.sin_family = AF_INET;

14 servaddr.sin_addr.s_addr = htonl(INADDR_ANY);

15 servaddr.sin_port = htons(13); /* сервер времени и даты */

16 Bind(listenfd, (SA*)&servaddr, sizeof(servaddr));

17 Listen(listenfd, LISTENQ);

18 for (;;) {

19 len = sizeof(cliaddr);

20 connfd = Accept(listenfd, (SA*)&cliaddr, &len);

21 printf("connection from %s, port %d\n",

22 Inet_ntop(AF_INET, &cliaddr.sin_addr, buff, sizeof(buff));

23 ntohs(cliaddr.sin_port));

24 ticks = time(NULL);

25 snprintf(buff, sizeof(buff), "% 24s\r\n", ctime(&ticks));

26 Write(connfd, buff, strlen(buff));

27 Close(connfd);

28 }

29 }

Новые объявления

7-8
Мы определяем две новых переменных:
len
, которая будет переменной типа «значение-результат», и
cliaddr
, которая будет содержать адрес протокола клиента.

Принятие соединения и вывод адреса клиента

19-23
Мы инициализируем переменную
len
, присвоив ей значение, равное размеру структуры адреса сокета, и передаем указатель на структуру
cliaddr
и указатель на
len
в качестве второго и третьего аргументов функции
accept
. Мы вызываем функцию
inet_ntop
(см. раздел 3.7) для преобразования 32-битового IP-адреса в структуре адреса сокета в строку ASCII (точечно-десятичную запись), а затем вызываем функцию
ntohs
(см. раздел 3.4) для преобразования сетевого порядка байтов в 16-битовом номере порта в порядок байтов узла.

ПРИМЕЧАНИЕ

При вызове функции sock_ntop вместо inet_ntop наш сервер станет меньше зависеть от протокола, однако он все равно зависит от IPv4. Мы покажем версию этого сервера, не зависящего от протокола, в листинге 11.7.

Если мы запустим наш новый сервер, а затем запустим клиент на том же узле, то дважды соединившись с сервером, мы получим от клиента следующий вывод:

solaris % daytimetcpcli 127.0.0.1

Thu Sep 11 12:44:00 2003

solaris % daytimetcpcli 192.168.1.20

Thu Sep 11 12:44:09 2003

Сначала мы задаем IP-адрес сервера как адрес закольцовки на себя (loopback address) (127.0.0.1), а затем как его собственный IP-адрес (192.168.1.20). Вот соответствующий вывод сервера:

solaris # daytimetcpsrv1

connection from 127.0.0.1, port 43388

connection from 192.168.1.20, port 43389

Поделиться:
Популярные книги

Месть бывшему. Замуж за босса

Россиус Анна
3. Власть. Страсть. Любовь
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Месть бывшему. Замуж за босса

Корсар

Русич Антон
Вселенная EVE Online
Фантастика:
боевая фантастика
космическая фантастика
6.29
рейтинг книги
Корсар

Последний попаданец

Зубов Константин
1. Последний попаданец
Фантастика:
фэнтези
попаданцы
рпг
5.00
рейтинг книги
Последний попаданец

Уязвимость

Рам Янка
Любовные романы:
современные любовные романы
7.44
рейтинг книги
Уязвимость

Последняя Арена 4

Греков Сергей
4. Последняя Арена
Фантастика:
рпг
постапокалипсис
5.00
рейтинг книги
Последняя Арена 4

Прометей: владыка моря

Рави Ивар
5. Прометей
Фантастика:
фэнтези
5.97
рейтинг книги
Прометей: владыка моря

Ваше Сиятельство 8

Моури Эрли
8. Ваше Сиятельство
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Ваше Сиятельство 8

Титан империи 4

Артемов Александр Александрович
4. Титан Империи
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Титан империи 4

Прометей: каменный век II

Рави Ивар
2. Прометей
Фантастика:
альтернативная история
7.40
рейтинг книги
Прометей: каменный век II

Наизнанку

Юнина Наталья
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Наизнанку

Вечная Война. Книга VIII

Винокуров Юрий
8. Вечная Война
Фантастика:
боевая фантастика
юмористическая фантастика
космическая фантастика
7.09
рейтинг книги
Вечная Война. Книга VIII

Генерал-адмирал. Тетралогия

Злотников Роман Валерьевич
Генерал-адмирал
Фантастика:
альтернативная история
8.71
рейтинг книги
Генерал-адмирал. Тетралогия

Идеальный мир для Лекаря 6

Сапфир Олег
6. Лекарь
Фантастика:
фэнтези
юмористическая фантастика
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 6

Сумеречный Стрелок 5

Карелин Сергей Витальевич
5. Сумеречный стрелок
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Сумеречный Стрелок 5