Вход/Регистрация
UNIX: разработка сетевых приложений
вернуться

Стивенс Уильям Ричард

Шрифт:

4 {

5 int c, sockfd, len = 0;

6 u_char *ptr = NULL;

7 struct addrinfo *ai;

8 if (argc < 2)

9 err_quit("usage: tcpcli01 [ -[gG] <hostname> ... ] <hostname>");

10 opterr = 0; /* отключаем запись сообщений getopt в stderr */

11 while ((с = getopt(argc, argv, "gG")) != -1) {

12 switch (c) {

13 case 'g': /* свободный маршрут от отправителя */

14 if (ptr)

15 err_quit("can't use both -g and -G");

16 ptr = inet_srcrt_init(0);

17 break;

18 case 'G': /* жесткий маршрут от отправителя */

19 if (ptr)

20 err_qint("can't use both -g and -G");

21 ptr = inet_srcrt_init(1);

22 break;

23 case '?':

24 err_quit("unrecognized option: %c", c);

25 }

26 }

27 if (ptr)

28 while (optind < argc-1)

29 len = inet_srcrt_add(argv[optind++]);

30 else if (optind < argc-1)

31 err_quit("need -g or -G to specify route");

32 if (optind != argc-1)

33 err_quit("missing <hostname>");

34 ai = Host_serv(argv[optind], SERV_PORT_STR, AF_INET, SOCK_STREAM);

35 sockfd = Socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);

36 if (ptr) {

37 len = inet_srcrt_add(argv[optind]); /* получатель в конце */

38 Setsockopt(sockfd, IPPROTO_IP, IP_OPTIONS, ptr, len);

39 free(ptr);

40 }

41 Connect(sockfd, ai->ai_addr, ai->ai_addrlen);

42 str_cli(stdin, sockfd); /* вызов рабочей функции */

43 exit(0);

44 }

Обработка аргументов командной строки

12-26
Мы вызываем нашу функцию
inet_srcrt_init
, чтобы инициализировать маршрут от отправителя. Тип маршрутизации указывается при помощи параметра
– g
(свободная) или
– G
(жесткая).

27-33
Если указатель
ptr
установлен, значит, был указан параметр маршрутизации от отправителя, и все указанные промежуточные узлы добавляются к маршруту, подготовленному на предыдущем этапе функцией
inet_srcrt_add
. Если же
ptr
не установлен, но в командной строке еще есть аргументы, значит, пользователь задал маршрут, но не указал его тип. В этом случае программа завершает работу с сообщением об ошибке.

Обработка адреса получателя и создание сокета

34-35
Последний аргумент командной строки — это имя узла или адрес сервера в точечно-десятичной записи, который обрабатывается нашей функцией
host_serv
. Мы не можем вызвать функцию
tcp_connect
, так как должны задать маршрут от отправителя между вызовом функций
socket
и
connect
. Последняя инициирует трехэтапное рукопожатие, а нам нужно, чтобы сегмент SYN отправителя и все последующие пакеты проходили по одному и тому же маршруту.

36-42
Если маршрут от отправителя задан, следует добавить IP-адрес сервера в конец списка адресов (см. рис. 27.1). Функция
setsockopt
устанавливает маршрут от отправителя для данного сокета. Затем мы вызываем функцию connect, а потом — нашу функцию
str_cli
(см. листинг 5.4).

Наш TCP-сервер имеет много общего с кодом, показанным в листинге 5.9, но содержит следующие изменения.

Во-первых, мы выделяем место для параметров:

int len;

  • Читать дальше
  • 1
  • ...
  • 373
  • 374
  • 375
  • 376
  • 377
  • 378
  • 379
  • 380
  • 381
  • 382
  • 383
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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