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

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

Жанры

Шрифт:

Завершая разговор о программном интерфейсе TLI, необходимо упомянуть об обработке ошибок. Для большинства функций TLI свидетельством ошибки является получение -1 в качестве возвращаемого значения. Напротив, в случае нормального завершения эти функции возвращают 0. Как правило, при неудачном завершении функции TLI код ошибки сохраняется в переменной

t_errno
, подобно тому, как переменная
errno
хранит код ошибки системного вызова. Для вывода сообщения, расшифровывающего причину ошибки, используется функция t_error(3N):

#include <tiuser.h>

void t_error(const char *errmsg);

При

вызове t_error(3N) после неудачного завершения какой-либо функции TLI будет выведено сообщение
errmsg
, определенное разработчиком программы, за которым последует расшифровка ошибки, связанной с кодом
t_errno
. Если значение
t_errno
равно
TSYSERR
, то расшифровка представляет собой стандартное сообщение о системной ошибке, связанной с переменной
errno
.

В заключение в качестве иллюстрации программного интерфейса TLI приведем пример приложения клиент-сервер. Как и в предыдущих примерах, сервер принимает сообщения от клиента и отправляет их обратно. Клиент, в свою очередь, выводит полученное сообщение на экран. В качестве сообщения, как и прежде, выступает жизнерадостное приветствие "Здравствуй, мир!".

Сервер

#include <sys/types.h>

#include <sys/socket.h>

#include <tiuser.h>

#include <netinet/in.h>

#include <arpa/inet.h>

#include <stdio.h>

#include <fcntl.h>

#include <netdb.h>

/* Номер порта, известный клиентам */

#define PORTNUM 1500

main(argc, argv)

int argc;

char *argv[];

{

 /* Дескрипторы транспортных узлов сервера */

 int tn, ntn;

 int pid, flags;

 int nport;

 /* Адреса транспортных узлов сервера и клиента */

 struct sockaddr_in serv_addr, *clnt_addr;

 struct hostent *hp;

 char buf[80], hname[80];

 struct t_bind req;

 struct t_call *call;

 /* Создадим транспортный узел. В качестве поставщика

транспортных услуг выберем модуль TCP */

 if ((tn = t_open("/dev/tcp", O_RDWR, NULL)) == -1) {

t_error("Ошибка
вызова t_open");

exit(1);

 }

 /* Зададим адрес транспортного узла — он должен быть

известен клиенту */

 nport = PORTNUM;

 /* Приведем в соответствие порядок следования байтов для хоста

и сети */

 nport = htons((u_short)nport);

 bzero(&serv_addr, sizeof(serv_addr));

 serv_addr.sin_family = AF_INET;

 serv_addr.sin_addr.s_addr = INADDR_ANY;

 serv_addr.sin_port = nport;

 req.addr.maxlen = sizeof(serv_addr);

 req.addr.len = sizeof(serv_addr);

 req.addr.buf = (char*)&serv_addr;

 /* Максимальное число запросов, ожидающих обработки,

установим равным 5 */

 req.qlen = 5;

 /* Свяжем узел с запросом */

 if (t_bind(tn, &req, (struct t_bind*)0) < 0) {

t_error("Ошибка вызова t_bind;

exit(1);

 }

 fprintf(stderr, "Адрес сервера: %s\n",

inet_ntoa(serv_addr.sin_addr));

 /* Поскольку в структуре t_call нам понадобится только буфер

для хранения адреса клиента, разместим ее динамически */

 if ((call =

(struct t_call*)t_alloc(tn, T_CALL, T_ADDR)) == NULL) {

t_error("Ошибка вызова t_alloc");

exit(2);

 }

 call->addr.maxlen = sizeof(serv_addr);

 call->addr.len = sizeof(srv_addr);

 call->opt.len = 0;

 call->update.len = 0;

 /* Бесконечный цикл получения и обработки запросов */

 while (1) {

/* Ждем поступления запроса на установление соединения */

if (t_listen(s, call) < 0) {

t_error("Ошибка вызова t_listen");

exit(1);

}

/* Выведем информацию о клиенте, сделавшем запрос */

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

Инцел на службе демоницы 1 и 2: Секса будет много

Блум М.
Инцел на службе демоницы
Фантастика:
фэнтези
5.25
рейтинг книги
Инцел на службе демоницы 1 и 2: Секса будет много

Весь цикл «Десантник на престоле». Шесть книг

Ланцов Михаил Алексеевич
Десантник на престоле
Фантастика:
альтернативная история
8.38
рейтинг книги
Весь цикл «Десантник на престоле». Шесть книг

Предатель. Цена ошибки

Кучер Ая
Измена
Любовные романы:
современные любовные романы
5.75
рейтинг книги
Предатель. Цена ошибки

Жандарм 2

Семин Никита
2. Жандарм
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Жандарм 2

Прогрессор поневоле

Распопов Дмитрий Викторович
2. Фараон
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Прогрессор поневоле

Всемирная энциклопедия афоризмов. Собрание мудрости всех народов и времен

Агеева Елена А.
Документальная литература:
публицистика
5.40
рейтинг книги
Всемирная энциклопедия афоризмов. Собрание мудрости всех народов и времен

Истребитель. Ас из будущего

Корчевский Юрий Григорьевич
Фантастика:
боевая фантастика
попаданцы
альтернативная история
5.25
рейтинг книги
Истребитель. Ас из будущего

Очешуеть! Я - жена дракона?!

Амеличева Елена
Фантастика:
юмористическая фантастика
5.43
рейтинг книги
Очешуеть! Я - жена дракона?!

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

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

Треугольная шляпа. Пепита Хименес. Донья Перфекта. Кровь и песок.

Бласко Висенте Ибаньес
65. Библиотека всемирной литературы
Проза:
классическая проза
5.00
рейтинг книги
Треугольная шляпа.
Пепита Хименес.
Донья Перфекта.
Кровь и песок.

Измена. Жизнь заново

Верди Алиса
1. Измены
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Измена. Жизнь заново

Три `Д` для миллиардера. Свадебный салон

Тоцка Тала
Любовные романы:
современные любовные романы
короткие любовные романы
7.14
рейтинг книги
Три `Д` для миллиардера. Свадебный салон

Бастард Императора. Том 5

Орлов Андрей Юрьевич
5. Бастард Императора
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Бастард Императора. Том 5

Идеальный мир для Лекаря 21

Сапфир Олег
21. Лекарь
Фантастика:
фэнтези
юмористическое фэнтези
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 21