UNIX: разработка сетевых приложений
UNIX: разработка сетевых приложений читать книгу онлайн
Новое издание книги, посвященной созданию веб-серверов, клиент-серверных приложений или любого другого сетевого программного обеспечения в операционной системе UNIX, — классическое руководство по сетевым программным интерфейсам, в частности сокетам. Оно основано на трудах Уильяма Стивенса и полностью переработано и обновлено двумя ведущими экспертами по сетевому программированию. В книгу включено описание ключевых современных стандартов, реализаций и методов, она содержит большое количество иллюстрирующих примеров и может использоваться как учебник по программированию в сетях, так и в качестве справочника для опытных программистов.
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
long DISCON_reason; /* причина разрыва соединения */
long SEQ_number; /* порядковый номер */
};
Мы можем посмотреть, какие ошибки могут быть возвращены поставщиком. Сначала мы задаем IP-адрес узла, на котором не запущен сервер времени и даты:
solaris26 % <b>tpi_daytime 192.168.1.10</b>
tpi_connect2: T_DISCON_IND from conn (146)
Код 146 соответствует ошибке
ECONNREFUSED
solaris26 % <b>tpi_daytime 192.3.4.5</b>
tpi_connect2: T_DISCON_IND from conn (145)
На этот раз возвращается ошибка
ETIMEDOUT
solaris26 % <b>tpi_daytime 192.3.4.5</b>
tpi_connect2: T_DISCON_IND from conn (148)
На этот раз мы получаем ошибку
EHOSTUNREACH
Следующая функция, которую мы рассмотрим, — это
tpi_read
Листинг 31.5. Функция tpi_read: считывание данных из потока
//streams/tpi_read.c
1 #include "tpi_daytime.h"
2 ssize_t
3 tpi_read(int fd, void *buf, size_t len)
4 {
5 struct strbuf ctlbuf;
6 struct strbuf datbuf;
7 union T_primitives rcvbuf;
8 int flags;
9 ctlbuf maxlen = sizeof(union T_primitives);
10 ctlbuf.buf = (char*)&rcvbuf;
11 datbuf.maxlen = len;
12 datbuf.buf = buf;
13 datbuf.len = 0;
14 flags = 0;
15 Getmsg(fd, &ctlbuf, &datbuf, &flags);
16 if (ctlbuf.len >= (int)sizeof(long)) {
17 if (rcvbuf.type == T_DATA_IND)
18 return (datbuf.len);
19 else if (rcvbuf.type == T_ORDREL_IND)
20 return (0);
21 else
22 err_quit("tpi_read: unexpected type %d", rcvbuf.type);
23 } else if (ctlbuf.len == -1)
24 return (datbuf.len);
25 else
26 err_quit("tpi_read: bad length from getmsg");
27 }
9-26
getmsg
strbuf
■ Данные могут прибыть в виде сообщения
M_DATA
getmsg
■ Данные могут прибыть как сообщение
T_DATA_IND
T_data_ind
struct T_data_ind {
long PRIM_type; /* T_DATA_IND */
long MORE_flag; /* еще данные */
};
Если возвращено такое сообщение, мы игнорируем поле
MORE_flag
getmsg
■ Сообщение
T_ORDREL_IND
FIN
struct T_ordrel_ind {
long PRIM_type; /* T_ORDREL_IND */
};
Это нормальное завершение. Мы просто возвращаем нулевое значение, указывая вызывающему процессу, что по соединению получен признак конца файла.
■ Сообщение
T_DISCON_IND
tpi_close
Листинг 31.6. Функция tpi_close: отправка запроса о завершении собеседнику
//streams/tpi_close.c
1 #include "tpi_daytime.h"
2 void
3 tpi_close(int fd)
4 {
5 struct T_ordrel_req ordrel_req;
6 struct strbuf ctlbuf;
7 ordrel_req PRIM_type = T_ORDREL_REQ;
8 ctlbuf.len = sizeof(struct T_ordrel_req);
9 ctlbuf.buf = (char*)&ordrel_req;
10 Putmsg(fd, &ctlbuf, NULL, 0);
11 Close(fd);
12 }
7-10
T_ordrel_req
struct T_ordrel_req {
long PRIM_type; /* T_ORDREL_REQ */