Читать книгу 📗 "Операционная система UNIX - Робачевский Андрей Михайлович"
/* Номер порта, который обслуживается сервером */#define PORTNUM 1500main (argc, argv)char *argv[];int argc;{ int s; int pid; int i, j; struct sockaddr_in serv_addr; struct hostent *hp; char buf[80]="Hello, World!"; /* В качестве аргумента клиенту передается доменное имя хоста, на котором запущен сервер. Произведем трансляцию доменного имени в адрес */ if ((hp = gethostbyname(argv[1])) == 0) { perror("Ошибка вызова gethostbyname()"); exit(3); } bzero(&serv_addr, sizeof(serv_addr)); bcopy(hp->h_addr, &serv_addr.sin_addr, hp->h_length); serv_addr.sin_family = hp->h_addrtype; serv_addr.sin_port = htons(PORTNUM); /* Создадим сокет */ if ((s = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("Ошибка вызова socket!)"); exit(1); } fprintf(stderr, "Адрес клиента: %sn", inet_ntoa(serv_addr.sin_addr)); /* Создадим виртуальный канал */ if (connect (s, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) == -1) { perror("Ошибка вызова connect()"); exit(1); } /* Отправим серверу сообщение и получим его обратно */ send(s, buf, sizeof(buf), 0); if (recv(s, buf, sizeof(buf) , 0) < 0) { perror("Ошибка вызова recv()"); exit(1); } /* Выведем полученное сообщение на экран */ printf("Получено от сервера: %sn", buf); close(s); printf("Клиент завершил работу nn");}Программный интерфейс TLI
При обсуждении реализации сетевой поддержки в BSD UNIX был рассмотрен программный интерфейс доступа к сетевым ресурсам, основанный на сокетах. В данном разделе описан интерфейс транспортного уровня (Transport Layer Interface, TLI), который обеспечивает взаимодействие прикладных программ с транспортными протоколами.
TLI был впервые представлен в UNIX System V Release 3.0 в 1986 году. Этот программный интерфейс тесно связан с сетевой подсистемой UNIX, основанной на архитектуре STREAMS, изолируя от прикладной программы особенности сетевой архитектуры. Вместо того чтобы непосредственно пользоваться общими функциями STREAMS, рассмотренными в предыдущей главе, TLI позволяет использовать специальный набор вызовов, специально предназначенных для сетевых приложений. Для преобразования вызовов TLI в функции интерфейса STREAMS используется библиотека TLI, которая в большинстве систем UNIX имеет название libnsl.a или libnsl.so.
Схема использования функций TLI во многом сходна с рассмотренным интерфейсом сокетов и зависит от типа используемого протокола — с предварительным установлением соединения (например, TCP) или без него (например, UDP).
На рис. 6.18 и 6.19 представлены схемы использования функций TLI для транспортных протоколов с предварительным установлением соединения и без установления соединения. Можно отметить, что эти схемы очень похожи на те, с которыми мы уже встречались в разделе "Межпроцессное взаимодействие в BSD UNIX. Сокеты" главы 3 при обсуждении сокетов. Некоторые различия отмечены ниже при описании функций TLI.

Рис. 6.18. Схема вызова функций TLI для протокола с предварительным установлением соединения

Рис. 6.19. Схема вызова функций TLI для протокола без предварительного установления соединения
Прежде чем перейти к обсуждению функций TLI, остановимся на определении адреса коммуникационного узла. TLI не накладывает никаких ограничений на формат адреса, возлагая интерпретацию на протоколы нижнего уровня. Благодаря этому, один и тот же интерфейс может быть использован при работе с различными семействами сетевых протоколов.
Для определения адреса TLI предоставляет общую структуру данных
netbufstruct netbuf { unsigned int maxlen; unsigned int len; char *buf;}Поле
bufmaxlenlensockaddrnetbufСтруктура
netbuf#include <tiuser.h>