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

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

Жанры

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

39 clientdone:

40 Close(unixfd);

41 if (recvfd >= 0)

42 Close(recvfd);

43 FD_CLR(unixfd, &allset);

44 client[i].connfd = -1;

45 return(--nready);

46 }

Получение номера порта, связанного с сокетом UDP

21-25
Вызывается функция
getsockname
,
так что демон может получить номер порта, связанного с сокетом. Поскольку неизвестно, каков размер буфера, необходимого для размещения структуры адреса сокета, мы используем структуру
sockaddr_storage
, которая достаточно велика для структуры адреса сокета любого поддерживаемого системой типа и обеспечивает нужное выравнивание.

26-33
Семейство адресов сокета вместе с номером порта сохраняется в структуре
client
. Если номер порта равен нулю, мы вызываем функцию
sock_bind_wild
для связывания универсального адреса и динамически назначаемого порта с сокетом, но, как отмечалось ранее, такой подход не работает в реализациях SVR4.

Сообщение клиенту об успехе

34
Один байт, содержащий символ
"1"
, отправляется обратно клиенту.

Закрытие UDP-сокета клиента

35
Заканчиваем работу с UDP-сокетом клиента и закрываем его с помощью функции
close
. Дескриптор был переслан нам клиентом и, таким образом, является копией; следовательно, UDP-сокет все еще открыт на стороне клиента.

Обработка ошибок и завершение работы клиента

37-45
Если происходит ошибка, клиент получает нулевой байт. Когда клиент завершается, наша часть доменного сокета Unix закрывается, и соответствующий дескриптор удаляется из набора дескрипторов для функции
select
. Полю
connfd
структуры
client
присваивается значение -1, что является указанием на ее освобождение.

Функция

readable_v4
вызывается, когда символьный сокет ICMPv4 открыт для чтения. Первая часть данной функции приведена в листинге 28.29. Этот код аналогичен коду для ICMPv4, приведенному ранее в листингах 28.6 и 28.15.

Листинг 28.29. Обработка полученных дейтаграмм ICMPv4, первая часть

//icmpd/readable_v4.c

1 #include "icmpd.h"

2 #include <netinet/in_systm.h>

3 #include <netinet/ip.h>

4 #include <netinet/ip_icmp.h>

5 #include <netinet/udp.h>

6 int

7 readable_v4(void)

8 {

9 int i, hlen1, hlen2, icmplen, sport;

10 char buf[MAXLINE];

11 char srcstr[INET_ADDRSTRLEN], dststr[INET_ADDRSTRLEN];

12 ssize_t n;

13 socklen_t len;

14 struct ip *ip, *hip;

15 struct icmp *icmp;

16 struct udphdr *udp;

17 struct sockaddr_in from, dest;

18 struct icmpd_err icmpd_err;

19 len = sizeof(from);

20 n = Recvfrom(fd4, buf, MAXLINE, 0, (SA*)&from, &len);

21 printf("%d bytes ICMPv4 from %s:", n, Sock_ntop_host((SA*)&from, len));

22 ip = (struct ip*)buf; /*
начало IP-заголовка */

23 hlen1 = ip->ip_hl << 2; /* длина IP-заголовка */

24 icmp = (struct icmp*)(buf + hlen1); /* начало ICMP-заголовка */

25 if ((icmplen = n - hlen1) < 8)

26 err_quit("icmplen (%d) < 8", icmplen);

27 printf(" type = %d, code = %d\n", icmp->icmp_type, icmp->icmp_code);

Функция выводит некоторую информацию о каждом получаемом сообщении ICMP. Это было сделано для отладки при разработке демона, и вывод управляется аргументом командной строки.

В листинге 28.30 приведена вторая часть функции

readable_v4
.

Листинг 28.30. Обработка полученных дейтаграмм ICMPv4, вторая часть

//icmpd/readable_v4.c

28 if (icmp->icmp_type == ICMP_UNREACH ||

29 icmp->icmp_type ==ICMP_TIMXCEED ||

30 icmp->icmp_type == ICMP_SOURCEQUENCH) {

31 if (icmplen < 8 + 20 + 8)

32 err_quit("icmplen (%d) < 8 + 20 + 8, icmplen);

33 hip = (struct ip*)(buf + hlen1 + 8);

34 hlen2 = hip->ip_hl << 2;

35 printf("\tsrcip = %s, dstip = %s, proto = %d\n",

36 Inet_ntop(AF_INET, &hip->ip_src, srcstr, sizeof(srcstr)),

37 Inet_ntop(AF_INET, &hip->ip_dst, dststr, sizeof(dststr)),

38 hip->ip_p);

39 if (hip->ip_p == IPPROTO_UDP) {

40 udp = (struct udphdr*)(buf + hlen1 + 8 + hlen2);

41 sport = udp->uh_sport;

42 /* поиск доменного сокета клиента, отправка заголовка */

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

Курсант: назад в СССР

Дамиров Рафаэль
1. Курсант
Фантастика:
попаданцы
альтернативная история
7.33
рейтинг книги
Курсант: назад в СССР

Чужая семья генерала драконов

Лунёва Мария
6. Генералы драконов
Фантастика:
фэнтези
5.00
рейтинг книги
Чужая семья генерала драконов

Пышка и Герцог

Ордина Ирина
Фантастика:
юмористическое фэнтези
историческое фэнтези
фэнтези
5.00
рейтинг книги
Пышка и Герцог

Имперский Курьер. Том 5

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

Имя нам Легион. Том 7

Дорничев Дмитрий
7. Меж двух миров
Фантастика:
боевая фантастика
рпг
аниме
5.00
рейтинг книги
Имя нам Легион. Том 7

Возвышение Меркурия

Кронос Александр
1. Меркурий
Фантастика:
героическая фантастика
попаданцы
аниме
5.00
рейтинг книги
Возвышение Меркурия

Законы Рода. Том 11

Андрей Мельник
11. Граф Берестьев
Фантастика:
юмористическое фэнтези
аниме
фэнтези
5.00
рейтинг книги
Законы Рода. Том 11

Измена. (Не)любимая жена олигарха

Лаванда Марго
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Измена. (Не)любимая жена олигарха

Вираж бытия

Ланцов Михаил Алексеевич
1. Фрунзе
Фантастика:
героическая фантастика
попаданцы
альтернативная история
6.86
рейтинг книги
Вираж бытия

Отмороженный 11.0

Гарцевич Евгений Александрович
11. Отмороженный
Фантастика:
боевая фантастика
рпг
попаданцы
фантастика: прочее
фэнтези
5.00
рейтинг книги
Отмороженный 11.0

История "не"мощной графини

Зимина Юлия
1. Истории неунывающих попаданок
Фантастика:
попаданцы
фэнтези
5.00
рейтинг книги
История немощной графини

Крестоносец

Ланцов Михаил Алексеевич
7. Помещик
Фантастика:
героическая фантастика
попаданцы
альтернативная история
5.00
рейтинг книги
Крестоносец

Газлайтер. Том 15

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

Призыватель нулевого ранга

Дубов Дмитрий
1. Эпоха Гардара
Фантастика:
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Призыватель нулевого ранга