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

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

Шрифт:

11 /* связываем произвольный локальный адрес */

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

13 myaddr.sin_family = AF_INET;

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

15 myaddr.sin_port = htons(0);

16 tpi_bind(fd, &myaddr, sizeof(struct sockaddr_in));

17 /* заполняем адрес сервера */

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

19 servaddr.sin_family = AF_INET;

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

21 Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);

22 tpi_connect(fd, &servaddr, sizeof(struct sockaddr_in));

23 for (;;) {

24 if ((n = tpi_read(fd, recvline, MAXLINE)) <= 0) {

25 if (n == 0)

26 break;

27 else

28 err_sys("tpi_read error");

29 }

30 recvline[n] = 0; /* завершающий нуль */

31 fputs(recvline, stdout);

32 }

33 tpi_close(fd);

34 exit(0);

35 }

Открытие транспортного устройства, связывание локального адреса

10-16
Мы открываем устройство, соответствующее поставщику транспортных служб (обычно
/dev/tcp
). Мы заполняем структуру адреса сокета Интернета значениями
INADDR_ANY
и 0 (для порта), указывая тем самым TCP связать произвольный локальный адрес с нашей точкой доступа. Мы вызываем свою собственную функцию
tpi_bind
(которая будет приведена чуть ниже) для выполнения этого связывания.

Заполнение структуры адреса сервера, установление соединения

17-22
Мы заполняем другую структуру адреса сокета Интернета, внося в нее IP-адрес сервера (из командной строки) и порт (13). Мы вызываем нашу функцию
tpi_connect
для установления соединения.

Считывание данных с сервера, копирование в стандартный поток вывода

23-33
Как и в случае других клиентов времени и даты, мы просто копируем данные, пришедшие по соединению, в стандартный поток вывода, останавливаясь при получении признака конца файла, присланного сервером (например, сегмент FIN). Мы сделали этот цикл похожим на тот, который использовался в коде сокетного клиента (см. листинг 1.1), поскольку наша функция
tpi_read
при нормальном завершении соединения на стороне сервера будет возвращать нулевое значение. Затем мы вызываем нашу функцию
tpi_close
для того, чтобы закрыть эту точку доступа.

Наша функция

tpi_bind
показана в листинге 31.3.

Листинг 31.3. Функция tpi_bind: связывание локального адреса с точкой доступа

//streams/tpi_bind.c

1 #include "tpi_daytime.h"

2 void

3 tpi_bind(int fd, const void *addr, size_t addrlen)

4 {

5 struct {

6 struct T_bind_req msg_hdr;

7 char addr[128];

8 } bind_req;

9 struct {

10 struct T_bind_ack msg_hdr;

11 char addr[128];

12 } bind_ack;

13 struct strbuf ctlbuf;

14 struct T_error_ack *error_ack;

15 int flags;

16 bind_req.msg_hdr.PRIM_type = T_BIND_REQ;

17 bind_req.msg_hdr.ADDR_length = addrlen;

18 bind_req.msg_hdr.ADDR_offset = sizeof(struct T_bind_req);

19 bind_req.msg_hdr.CONIND_number = 0;

20 memcpy(bind_req.addr, addr, addrlen); /* sockaddr_in{} */

21 ctlbuf.len = sizeof(struct T_bind_req) + addrlen;

22 ctlbuf.buf = (char*)&bind_req;

23 Putmsg(fd, &ctlbuf, NULL, 0);

  • Читать дальше
  • 1
  • ...
  • 453
  • 454
  • 455
  • 456
  • 457
  • 458
  • 459
  • 460
  • 461
  • 462
  • 463
  • ...

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

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

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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