Уильям Стивенс - UNIX: разработка сетевых приложений

Тут можно читать онлайн Уильям Стивенс - UNIX: разработка сетевых приложений - бесплатно ознакомительный отрывок. Жанр: comp-osnet, издательство Питер, год 2007. Здесь Вы можете читать ознакомительный отрывок из книги онлайн без регистрации и SMS на сайте лучшей интернет библиотеки ЛибКинг или прочесть краткое содержание (суть), предисловие и аннотацию. Так же сможете купить и скачать торрент в электронном формате fb2, найти и слушать аудиокнигу на русском языке или узнать сколько частей в серии и всего страниц в публикации. Читателям доступно смотреть обложку, картинки, описание и отзывы (комментарии) о произведении.
  • Название:
    UNIX: разработка сетевых приложений
  • Автор:
  • Жанр:
  • Издательство:
    Питер
  • Год:
    2007
  • Город:
    Санкт-Петербург
  • ISBN:
    5-94723-991-4
  • Рейтинг:
    4.33/5. Голосов: 91
  • Избранное:
    Добавить в избранное
  • Отзывы:
  • Ваша оценка:
    • 80
    • 1
    • 2
    • 3
    • 4
    • 5

Уильям Стивенс - UNIX: разработка сетевых приложений краткое содержание

UNIX: разработка сетевых приложений - описание и краткое содержание, автор Уильям Стивенс, читайте бесплатно онлайн на сайте электронной библиотеки LibKing.Ru

Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.

UNIX: разработка сетевых приложений - читать онлайн бесплатно ознакомительный отрывок

UNIX: разработка сетевых приложений - читать книгу онлайн бесплатно (ознакомительный отрывок), автор Уильям Стивенс
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать

7 * неотрицательные значения соответствуют всем прочим ошибкам ICMP

8 */

9 int

10 recv_v4(int seq, struct timeval *tv)

11 {

12 int hlen1, hlen2, icmplen, ret;

13 socklen_t len;

14 ssize_t n;

15 struct ip *ip, *hip;

16 struct icmp *icmp;

17 struct udphdr *udp;

18 gotalarm = 0;

19 alarm(3);

20 for (;;) {

21 if (gotalarm)

22 return(-3); /* истек таймер */

23 len = pr->salen;

24 n = recvfrom(recvfd, recvbuf, sizeof(recvbuf), 0, pr->sarecv, &len);

25 if (n

26 if (errno == EINTR)

27 continue;

28 else

29 err_sys("recvfrom error");

30 }

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

32 hlenl = ip->ip_hl icmp_type == ICMP_TIMXCEED &&

37 icmp->icmp_code == ICMP_TIMXCEED_INTRANS) {

38 if (icmplen

39 continue; /* недостаточно данных для проверки внутреннего IP */

40 hip = (struct ip*)(recvbuf + hlen1 + 8);

41 hlen2 = hip->ip_hl ip_p == IPPROTO_UDP &&

46 udp->uh_sport == htons(sport) &&

47 udp->uh_dport == htons(dport + seq)) {

48 ret = -2; /* ответил промежуточный маршрутизатор */

49 break;

50 }

51 } else if (icmp->icmp_type == ICMP_UNREACH) {

52 if (icmplen

53 continue; /* недостаточно данных для проверки внутреннего IP */

54 hip = (struct ip*)(recvbuf + hlen1 + 8);

55 hlen2 = hip->ip_hl ip_p == IPPROTO_UDP &&

60 udp->uh_sport == htons(sport) &&

61 udp->uh_dport == htons(dport + seq)) {

62 if (icmp->icmp_code == ICMP_UNREACH_PORT)

63 ret = -1; /* цель достигнута */

64 else

65 ret = icmp->icmp_code; /* 0, 1, 2, ... */

66 break;

67 }

68 }

69 if (verbose) {

70 printf(" (from %s: type = %d, code - %d)\n",

71 Sock_ntop_host(pr->sarecv, pr->salen),

72 icmp->icmp_type, icmp->icmp_code);

73 }

74 /* другая ICMP-ошибка, нужно снова вызвать recvfrom() */

75 }

76 alarm(0); /* отключаем таймер */

77 Gettimeofday(tv, NULL); /* время получения пакета */

78 return(ret);

79 }

Установка таймера и прочтение каждого ICMP-сообщения

17-27 Таймер устанавливается на 3 с, и функция входит в цикл, вызывающий recvfrom, считывая каждое ICMPv4-сообщение, возвращаемое на символьный сокет.

ПРИМЕЧАНИЕ

Эта функция не создает ситуации гонок, описанной в разделе 20.5, благодаря использованию глобального флага.

Извлечение указателя на ICMP-заголовок

31-35 Указатель указывает на начало IPv4-заголовка (напомним, что операция чтения на символьном сокете всегда возвращает IP-заголовок), а указатель icmpуказывает на начало ICMP-заголовка. На рис. 28.5 показаны различные заголовки, указатели и длины, используемые в данном коде.

Рис 286 Заголовки указатели и длины используемые при обработке ошибки - фото 135

Рис. 28.6. Заголовки, указатели и длины, используемые при обработке ошибки ICMPv6

Мы определяем две функции icmpcode_v4и icmpcode_v6, которые можно вызывать в конце функции traceloopдля вывода строки описания, соответствующей ICMP-ошибке недоступности получателя. В листинге 28.19 приведена IPv6-функция. IPv4-функция аналогична, хотя и длиннее, поскольку существует большее количество ICMPv4-кодов недоступности получателя (см. табл. А.5).

Последней функцией в нашей программе tracerouteявляется обработчик сигнала SIGALRM— функция sig_alrm, приведенная в листинге 28.17. Эта функция лишь возвращает ошибку EINTRиз функции recvfrom, как в случае функции recv_v4, так и в случае recv_v6.

Листинг 28.17. Функция sig_alrm

//traceroutе/sig_alrm.c

1 #include "trace.h"

2 int gotalarm;

3 void

4 sig_alrm(int signo)

5 {

6 gotalarm = 1; /* установка флага, оповещающего о сигнале */

7 return; /* прерывается работа функции recvfrom() */

8 }

Листинг 28.18. Функция recv_v6: чтение и обработка сообщений ICMPv6

//traceroute/recv_v6

1 #include "trace.h"

2 extern int gotalarm;

3 /*

4 * Возвращает; -3 при тайм-ауте

5 * -2 для сообщения ICMP time exceeded in transit (продолжаем поиск

маршрута)

6 * -1 для сообщения ICMP port unreachable (цель достигнута)

7 * неотрицательные значения соответствуют всем прочим ICMP-сообщениям

8 */

9 int

10 recv_v6(int seq, struct timeval *tv)

11 {

12 #ifdef IPV6

13 int hlen2, icmp6len, ret;

14 ssize_t n;

15 socklen_t len;

16 struct ip6_hdr *hip6;

17 struct icmp6_hdr *icmp6;

18 struct udphdr *udp;

19 gotalarm = 0;

20 alarm(3);

21 for (;;) {

22 if (gotalarm)

23 return(-3); /* истек таймер */

24 len = pr->salen;

25 n = recvfrom(recvfd, recvbuf, sizeof(recvbuf), 0, pr->sarecv, &len);

26 if (n

27 if (errno == EINTR)

28 continue;

29 else

30 err_sys("recvfrom error");

31 }

32 icmp6 = (struct icmp6_hdr*)recvbuf; /* ICMP-заголовок */

33 if ((icmp6len = n)

34 continue; /* недостаточно для проверки ICMP-заголовка */

35 if (icmp6->icmp6_type == ICMP6_TIME_EXCEEDED &&

36 icmp6->icmp6_code == ICMP6_TIME_EXCEED_TRANSIT) {

37 if (icmp6len

38 continue; /* недостаточно для проверки внутреннего заголовка */

39 hip6 = (struct ip6_hdr*)(recvbuf + 8);

40 hlen2 = sizeof(struct ip6_hdr);

41 udp = (struct udphdr*)(recvbuf + 8 + hlen2);

42 if (hip6->ip6_nxt == IPPROTO_UDP &&

43 udp->uh_sport == htons(sport) &&

44 udp->uh_dport == htons(dport + seq))

45 ret = -2; /* ответил промежуточный маршрутизатор */

46 break;

47 } else if (icmp6->icmp6_type == ICMP6_DST_UNREACH) {

48 if (icmp6len

49 continue; /* недостаточно для проверки внутреннего заголовка */

50 hip6 = (struct ip6_hdr*)(recvbuf + 8);

51 hlen2 = sizeof(struct ip6_hdr);

52 udp = (struct udphdr*)(recvbuf + 8 + hlen2);

53 if (hip6->ip6_nxt == IPPROTO_UDP &&

54 udp->uh_sport == htons(sport) &&

55 udp->uh_dport == htons(dport + seq)) {

56 if (icmp6->icmp6_code == ICMP6_DST_UNREACH_NOPORT)

57 ret = -1; /* цель достигнута */

58 else

59 ret = icmp6->icmp6_code; /* 0, 1, 2, ... */

60 break;

61 }

62 } else if (verbose) {

63 printf(" (from %s: type = %d, code = %d)\n",

64 Sock_ntop_host(pr->sarecv, pr->salen);

65 icmp6->icmp6_type, icmp6->icmp6_code);

66 }

67 /* другая ICMP-ошибка. нужно вызвать recvfrom() */

68 }

69 alarm(0); /* отключаем таймер */

70 Gettimeofday(tv, NULL); /* get time of packet arrival */

71 return(ret);

72 #endif

73 }

Листинг 28.19. Возвращение строки, соответствующей коду недоступности ICMPv6

//traceroute/icmpcode_v6.c

1 #include "trace.h"

2 const char *

3 icmpcode_v6(int code)

4 {

5 #ifdef IPV6

6 static char errbuf[100];

7 switch (code) {

8 case ICMP6_DST_UNREACH_NOROUTE:

9 return("no route to host");

10 case ICMP6_DST_UNREACH_ADMIN:

11 return("administratively prohibited");

12 case ICMP6_DST_UNREACH_NOTNEIGHBOR:

13 return("not a neighbor");

14 case ICMP6_DST_UNREACH_ADDR:

15 return("address unreachable");

15 case ICMP6_DST_UNREACH_NOPORT:

16 return("port unreachable");

17 default:

18 sprintf(errbuf, "[unknown code %d]",. code);

19 return errbuf;

20 }

Читать дальше
Тёмная тема
Сбросить

Интервал:

Закладка:

Сделать


Уильям Стивенс читать все книги автора по порядку

Уильям Стивенс - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки LibKing.




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


Отзывы читателей о книге UNIX: разработка сетевых приложений, автор: Уильям Стивенс. Читайте комментарии и мнения людей о произведении.


Понравилась книга? Поделитесь впечатлениями - оставьте Ваш отзыв или расскажите друзьям

Напишите свой комментарий
x