Программирование >>  Структура ядра и системные вызовы 

1 ... 62 63 64 [ 65 ] 66 67 68 ... 98


Аргумент info возвращает стандартные характеристики используемого провайдера транспорта. Эта информация обычно игнорируется, и фактическое значение info может быть равно 0. Если же пользователь хочет проверить стандартные характеристики, он должен определить переменную типа struct tjnfo и передать ее адрес в аргумент info. После того как рассматриваемая функция возврат1гг управление вызывающему процессу, пользователь сможет увидеть содержимое этой переменной. Интересующие его данные содержатся в поле info- >servtype, которое может иметь одно из перечисленных ниже значений.

Значение servtype Смысл

T COTS Провайдер транспорта позволяет устанавливать соединение

на основе виртуального канала, но не поддерживает функцию прекращения передачи сообщений только в одном из направлений

T COTSORD Провайдер транспорта позволяет устанавливать соединение

на основе виртуального канала и поддерживает функцию прекращения передачи сообщений только в одном из направлений

T CLTS Провайдер транспорта поддерживает передачу дейтаграм-

мных сообщений

Эти константы объявляются в заголовке <tiuser.h>. В случае неудачи рассматриваемая функция возвращает -1, а в случае успещного выполнения - дескриптор, который обозначает конечную точку транспортировки, созданную функцией.

Приведенные ниже операторы предназначены для создания ориентированной на соединение конечной точки транспортировки, которая поддерживает функцию прекращения передачи сообщений только в одном из направлений. Операции в этой конечной точке выполняются в неблокирующем режиме. Информация о стандартных характеристиках провайдера транспорта не запрашивается. Дескриптор конечной точки транспортировки присваивается переменной fd:

int fd = t open( /dev/ticotsord , 0 RDWR 0 NONBLOCK, 0) if (fd == -1) t error( t open ) ;

Рассмотрим операторы, предназначенные для создания дейтаграммной конечной точки транспортировки. Операции в этой конечной точке выполняются в блокирующем режиме. Информация о стандартных характеристиках провайдера транспорта возвращается в переменной info. Значение дескриптора конечной точки транспортировки присваивается переменной fd:

struct t info info;

int fd = t open( /dev/ticlts , 0 RDWR, Sinfo) if (fd == -1) t errorCt open );

Наиболее часто используемые конечные точки транспортировки имеют заранее определенные адреса, указанные в файле /etc/services. Например, следующие две записи этого файла определяют две конечные точки:

# /etc/services test 4045/tcp utstl 5001/udp

Здесь имя сервисной программы, использующей первую конечную точку транспортировки,- test, а в качестве провайдера транспорта используется протокол ТС?. Таким образом, это - конечная точка, ориентированная на соединение. Имя сервиса второй конечной точки транспортировки - utstl, а в качестве провайдера транспорта используется протокол UDP. Следовательно, это - дейтаграммная конечная точка.

При наличии в файле /etc/services таких определений адрес конечной точки транспортировки и имя файла устройства ее провайдера транспорта можно задать следующим образом:

struct nd hostserv hostserv; struct netconfig *nconf; struct nd addrlist *addr; void *hp;

int type = NC TPI COTS ORD;

if ((hp=setnetpath()) == 0)

perror( Cant init network ); exit(l);

hostserv.h host = fruit задается хост-имя машины hostserv.h serv = test задается имя сервисной программы while ((nconf=getnetpath(hp)) != 0) {

if (nconf->nc semantics == type

&& netdir getbyname(nconf, Shostserv, saddr)==0) break;

endnetpath(hp);

if (nconf == 0)

cerr No transport found for service: test \n ; else if ((tid=t open(nconf->nc device, 0 RDWR, 0) < 0)

t error ( t open fails ); else cerr transport end points address is specified in addr\n ;

В приведенном сегменте кода имя машины и имя сервисной программы задаются как fruit и test. Эта информация заносится в переменную hostserv. Функции setnetpath, getnetpath и endnetpath используются для обработки записей файла /etc/netconfig, каждая из которых содержит имя провайдера транспорта и имя соответствующего файла устройства. В этом примере программа ищет провайдер транспорта типа NC TPI COTS ORD (с установлением соединения и поддержкой разрыва соединения только в одном



из направлений). Для каждого провайдера транспорта, тип которого удовлетворяет этим кррггериям, в функцию netdir getbyname передаются переменные nconf и hostserv. Это позволяет найти, во-первых, адрес конечной точки транспортировки на указанной машине (в нашем примере - fruit) и, во-вторых, имя заданной сервисной программы {test).

Адрес конечной точки транспортировки возврашается с помошью переменной addr. Эта переменная используется позже в вызовах функций tjbind (серверный процесс) и tconnect (клиентский процесс).

Приведенный выше код можно модифицировать для получения адреса дейтаграммной конечной точки транспортировки. Этот адрес является путевым именем файла устройства, соответствующего заданному для сервиса utstl провайдеру транспорта. Модификация предусматривает следующие операции:

присвоить переменной type значение NC TPI CLTS вместо NC TPI COTS ORD;

указать в поле hostserv.h serv значение utstl.

11.4.3. Функция t bind

Прототип функции tjind выглядит следующим образом:

#include <tiuser.h>

int t bind ( int fd, struct t bind* inaddr, struct t bind* outaddr );

С помощью этой функции конечной точке транспортировки присваивается имя (или адрес). Дескриптор этой конечной точки указывается аргументом fd. Фактическое значение fd берется из вызова topen.

Аргумент inaddr содержит адрес, присвоенный конечной точке транспортировки. Его фактическое значение может быть NULL. Это означает, что адрес конечной точке должен присвоить провайдер транспорта.

Структура tJind объявляется следующим образом:

struct t bind {

struct netbuf unsigned

addr;

qlen;

Здесь поле qlen задает максимально допустимое для данной конечной точки транспортировки количество запросов на соединение. Применительно к серверной конечной точке транспортировки этому полю присваивается ненулевое значение, а для клиентских точек - нулевое. Поле addr содержит адрес, который должен быть присвоен конечной точке транспортировки.

CipyKTypa netbuf объявляется следующим образом: structnetbuf

unsigned int unsigned int char*

maxlen;

len;

buf;

Здесь значение len задает число символов в аргументе buf который содержит адрес конечной точки транспортировки. Значение аргумента maxlen в данном случае не используется.

В аргументе outaddr возвращается фактический адрес, присвоенный конечной точке транспортировки используемым провайдером транспорта. Этот адрес может отличаться от того, который указан в inaddr Если провайдер транспорта не может назначить конечной точке адрес, указанный в inaddr, он назначает ей другой адрес. Фактическое значение аргумента outaddr может быть равно NULL. Это означает, что вызывающему процессу безразлично, какой адрес назначается данной конечной точке транспортировки. Такая ситуация обычно характерна для клиентских конечных точек транспортировки, функционирующих в режиме с установлением соединения.

Если значение аргумента outaddr - адрес переменной типа struct tJind, то outaddr->buf является адресом буфера, определенного вызывающим процессом, а в поле outaddr->maxlen задается максимальный размер буфера outaddr->buf. При выходе из функции поле outaddr->len содержит число символов, имеющихся в outaddr->buf, где хранится адрес конечной точки транспортировки, назначенный провайдером транспорта.

В случае успешного выполнения эта функция возвращает О, а в случае неудачи возвращает -1

Ниже конечной точке транспортировки, указанной аргументом/с, назначается адрес, возвращаемый функцией netdir getbyname (см. пример из пре-дьщущего раздела). Данная конечная точка одновременно может принимать до пяти клиентских запросов на соединение. Функция t alloc динамически вьщеляет память объекту типа struct tjin (на который указывает переменная bind). Это гарантирует правильную инициализацию всех полей названного объекта.

struct t bind *bind = t alloc(fd, T BIND, T ALL); if (Ibind)

t error( t alloc fails for T BIND ); else (

bind->qlen =.5;

bind->addr = *(addr->n addrs); if (t bind(fd, bind, bind) < 0) t error( t bind );

Конечной точке транспортировки можно присвоить адрес целочисленного типа. Это полезно, если данная точка взаимодействует с другими конечными точками транспортировки только на этой машине. В следующей



программе конечной точке транспортировки, указанной аргументбм fd, присваивается адрес, значение которого равно 2: /

struct t bind *bind = t alloc(fd, T BIND, T ALL) ;

if (bind) { i

bind->qlen =5; f

bind->addr.len = sizeof(int)

*(int)bind->addr.buf = 2;;

if (t bind(fd, bind, bind) < 0) t error( t bind ); ) else t error( t alloc fails for T BIND ); )

11.4.4. Функция tjisten

Прототип функции t listen выглядит так:

#include <tiuser.h>

int tjisten ( int fd, struct t call* call);

Эта функция ожидает прибытия в конечную точку транспортировки, указанную аргументом fd, клиентского запроса на соединение. Адрес клиентской конечной точки транспортировки возвращается посредством аргумента call.

По умолчанию эта функция блокирует вызывающий процесс до тех пор, пока не будет получен клиентский запрос на соединение. Если же точка fd задана как неблокирующая (с помощью флага ONONBLOCK в вызове tcall или посредством функции fcntl), то tjisten возвращает управление немедленно (при условии, что ни одного клиентского запроса не обнаружено). Глобальной переменной terrno присваивается значение TNODATA.

Структура t call объявляется следующим образом:

struct t call

struct addr;

struct netbuf opt; struct netbuf udata; int sequence;

Здесь поле addr содержит адрес клиентской конечной точки транспортировки, которая инициирует посылку запроса на соединение. В поле opt устанавливаются параметры, зависящие от протокола. В поле udata указываются необязательные пользовательские данные, которые должны бьггь посланы вместе с запросом на соединение. Поле sequence содержит целочисленный идентификатор, используемый для уникального обозначения каждого соединения.

В\следующем примере проверяется наличие запроса на соединение в неблокирующем режиме. С помощью вызова функции t alloc для переменной call динамически выделяется память. Такой способ вьщеления памяти гарантирует, что поля maxlen в аргументах addr, opt и udata будут отражать размеры соответствующих полей buf.

struct t call *call = (struct t call*)t alloC(fd, T CALLOC, T ALL); if (icall)

t error( t alloc fails for T CALL ); KV-.

else do ( ; Gi.

if (t listen (fd, call) === 0) brea)c; /* получен запрос на

соединение */

if (t errno != TNODATA) (

t error( t listen fails ); exit (1);

/* выполнять другие операции */ } while(1);

В этом примере сначала вызывается функция t alloc, которая динамически вьщеляет память под объект struct t call и указывает на него переменной call. После этого начинается цикл, в котором вызывается функция tjisten, итеративно проверяющая наличие запросов на соединение. Возврат данной функцией нулевого значения говорит о том, что такой запрос имеется, и программа выходит из цикла. Когда tjisten возвращает ненулевое значение, проверяется глобальная переменная terrno. Если ее значением является TNODATA, значит возникла какая-то иная ощибка. В таком случае программа вызывает функцию t error для вьщачи диагностического сообщения, а затем заверщается. Какое-либо иное значение этой переменной говорит о том, что запрос на соединение еще не поступил, и программа выполняет другие операции, после чего возобновляет вызов tjisten.

11.4.5. Функция t accept

Прототип функции t accept выглядит следующим образом:

#include <tiuser.h>

int tjaccept ( int fd, int newfd, struct t call* call );

Эта функция принимает клиентский запрос на соединение, обнаруженный посредством вызова tjisten.

Аргумент та указывает, какая серверная конечная точка транспортировки принимает запрос на соединение. Посредством аргумента newfd задается конечная точка, которая должна быть соединена с клиентской конечной точкой транспортировки. Значение newfd может как совпадать с fd, так и не совпадать. В первом случае в данной конечной точке транспортировки не



1 ... 62 63 64 [ 65 ] 66 67 68 ... 98

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика