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

1 ... 64 65 66 [ 67 ] 68 69 70 ... 98


if < t ud) < cr-.iVfv/ ft;

t error( t alloc for T UNIDATAfails ); ,

exit (11;

int flags; char buf[80];

t ud->tidata.len = sizeof(buf); /* организовать буфер для приема

сообщения */

t ud->udata.buf = buf;

if (t rcvudata(fd, t ud, Sflags) < 0) ( /* принять дейтаграммное

сообщение */

if (t errno==TLOOK) ( struct t uderr *uderr =

(struct t uderr*)t alloc(fd, T UDERROR, T ALL};

if (luderr) {

t error( t alloc for T UDERROR fails );

exit(2);

if (t rcvuderr(fd, udert) < 0) /* получить код ошибки */

t error( t uderr ); else cerr Error codeis: aderr->error endl; t free(uderr, T UDERROR); /* удалить запись с данными

об ошибках */

else t error( t rcvudata ); } else cout receive msg: buf \n ;

11,4.9. Функции t sndrel, t rcvrel

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

#include <tiuser.h>

int t sndrel ( int fd ); int t rcvrel ( int fd );

Функция t sndrel передает запрос в используемый провайдер транспорта на разрыв соединения только в одном направлении. Процесс не может посылать сообщения в конечную точку транспортировки, обозначенную аргументом fd, но может продолжать принимать сообщения через эту точку (до получения подтверждения о приеме запроса на разрыв соединения).

В случае успещного выполнения эта функция возвращает О, а в случае неудачи возвращает -1. Если точка fd задана как неблокирующая и запрос на разрыв соединения в одном направлении не может бьггь передан в используемый провайдер транспорта немедленно, функция возвращает -1 и переменной t ermo присваивается значение TFLOW.

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

Функции t sndrel и t rcvrel поддерживаются не всеми провайдерами транспорта. Если провайдер не поддерживает эти функции, а они вызываются то возвращается значение -1 и переменной t errno присваивается значение TNOTSUPPORT.

В следующем примере показано, как в конечную точку транспортировки посылается запрос на разрыв соединения в одном направлении. Затем программа ждет подтверждения уведомления о разрыве соединения:

if (sndrel(fd) <0)

t error( sndrel ); else if (t rcvrel(fd) < 0) t error( rcvrel );

11.4.10. Функции t snddls, t rcvdis

Прототипы функций t snddis и t rcvdis:

#include <tiuser.h>

int t snddis ( int fd. struct t call* call ); int tjrcvdis ( int fd, struct t discon* conn );

Функция t snddis служит для аварийного разрыва установленного ранее транспортного соединения и отклонения клиентского запроса на соединение. При отклонении запроса на соединение в поле call- >sequence указывается, какой запрос отклоняется. При аварийном разрыве соединения аргумент call может иметь значение NULL; в противном случае используется только поле call->udata, в котором содержатся пользовательские данные, передаваемые в удаленную транспортную точку вместе с уведомлением об аварийном разъединении.

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

Функция t rc\dis служит для отправки уведомления об аварийном разрыве соединения и отправки вместе с уведомлением пользовательских данных. Аргумент conn может иметь значение NULL, если процесс не запрашивает о пользовательских данных и причине преждевременного расторжения. В противном случае conn содержит адрес переменной типа struct t discon. Эта структура объявляется следующим образом:

struct t discon

ftruct netbuf udata;

reason;

sequence;



Поле conn->udata содержит пользовательские данные, переданные одновременно с вызовом tsnddis. Поле com->reason содержит код причины разъединения, который зависит от провайдера транспорта. Поле conn->se-quence имеет значение только для серверного процесса, выполнившего несколько вызовов tjisten, и используется для того, чтобы определить, какой клиентский процесс инициировал вызов tconnect и, затем, вызов tsnddis.

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

В следующем примере в конечную точку транспортировки посылается запрос на аварийный разрыв соединения: if (t snddis(fd) < 0) t error( t snddis );

Ниже функция t rcvdis используется для получения кода хфичины отклонения запроса на соединение:

if (t connect(fd, call, call) < && t errno==TLOOK) if (t loolc(fd)==T DISCONNECT) {

Struct t discon *conn = (struct t discon*)t alloc(fd, T DIS, T ALL); if (Iconn)

t error( t alloc for T DIS fails ); else if (t rcvdis(fd, conn) < 0)

t error( t rcvdis ); else cout Disconnect reason code: conn->reason endl:

11.4.11. Функция t close

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

#include <tiuser.h> int tjclose ( int fd );

Функция tclose заставляет провайдер транспорта освободить все системные ресурсы, которые выделены для конечной точки транспортировки, указанной аргументом fd, и закрывает файл устройства, связанный с этим провайдером. Данную функцию следует вызывать после завершения соединения с транспортной конечной точкой, осуществленного посредством вызова tsndrel или tsnddis.

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

Вот как можно закрыть конечную точку транспортировки:

if (t close(fd) < 0) t error( t close );

11.5. Класс TLI

в этом разделе описан класс ТЫ, который выполняет функции, похожие на функции класса sock (см. раздел 11.2). В частности, класс ТЫ инкапсулирует все низкоуровневые интерфейсы системных вызовов ТЫ и обеспечивает управление динамической памятью, используемой для хранения ТЫ-данных (таких как struct tcall, struct tJind и т.д.). Это позволяет сократить время обучения и программирования для тех пользователей, которые хотят с помощью интерфейса транспортного уровня решать задачи межпроцессного взаимодействия. Кроме того, класс ТЫ способствует максимальной унификации пользовательских приложений.

Класс ТЫ определяется в заголовке tli.h следующим образом:

#ifndef TLI H ♦define TLI H

/* Определение класса тЫ */ ♦include <iostream.h> ♦include <unistd.h> ♦include <string.h> ♦include <tiuser.h>

♦include <stropts.h> *

♦include <fcntl.h>

♦include <stdio.h>

♦include <stdlib.h>

tinclude <signal.h>

♦include <netdir.h>

♦include <netconfig.li>

♦define UDP TRANS /dev/ticlts ♦define TCP TRANS /dev/ticotsord ♦define DISCONNECT -1

class tli { private: int tid; int local addr; struct nd addrlist struct netconfig

int rc;

дескриптор транспорта

/* адрес транспорта для локального IPC */ *addr; /* адрес транспорта для сетевого IPC */ *nconf; /* файл устройства провайдера транспорта */ ТЫ functions return status code

/* вьщелить структуру для передачи дейтаграммного сообщения

в конечную точку сети Internet */ struct t unitdata* alloc ud ( int nsid, char* service,

char* host )

struct t unitdata* ud=(struct t unitdata*)t alloc(

nsid==-l ? tid : nsid, (T UNITDATA), (T ALL));

if (!ud)



t error( t alloc of t unitdata ); return 0;

struct nd hostserv hostserv;

struct netconfig *ncf; TI address

struct nd addrlist *Addr;

void *hp;

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

perror( Cant init network ); return 0;

hostserv.h host = host; hostserv.h serv = service; while ({ncf=getnetpath(hp)) != 0) (

if (ncf->nc semantics == NC TPI CLTS

S& netdir getbyname(ncf, shostserv, &Addr)==0) break;

endnetpath(hp) ; if (Incf) {

cerr Cant find transport for service

\n ;

return 0;

ud->addr = *{Addr->n addrs); return ud;

/* выделить структуру для передачи дейтаграммного сообщения

в конечную точку */

struct t unitdata* alloc ud { int nsid, int port no )

struct t unitdata* ud={struct t unitdata*)t alloc{

nsid==-l ? tid : nsid, (T UNITDATA), {T ALL));

if {!ud)

t error{ t alloc of t unitdata ); return 0;

ud->addr.len = sizeof(int); *(int*)ud->addr.buf = port no; return ud;

public:

/* конструктор, обеспечивающий создание конечной

транспортной точки для локального IPC */ tli{ int srv addr, int connless = 0 ) {

localaddr = srv addr; nconf =0; addr =0;

if {{tid t open(connless ? UDP TRANS : TCP TRANS, 0 RDWR, 0)) < 0) t error{ t open fails );

/* конструктор, обеспечивающий создание конечной

транспортной точки для сетевого IPC */ tli{ char* hostname, char* service, int connless=0 )

struct nd hostserv hostserv; void *hp;

int type = connless ? NC TPI CLTS : NC TPI COTS ORD; local addr = 0;

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

и сервиса */ if ({hp=setnetpath{)) == 0) {

perror( Cant init network ); exitd) ;

hostserv.h host = hostname; hostserv.h serv = service; 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: service \n ; else if {{tid=t open(nconf->nc device, 0 RDWR, 0)) < 0)

t error( t open fails );

/* функция-деструктор */

~tli() { shutdown 0; close {tid); );

/* проверить статус успешного выполнения конструктора */ int good О { return tid >= 0; );

/* позволить провайдеру транспорта г1рисвоить имя конечной

точке */ .

int Bind anonymous{ ) {

return t bind{tid. О, 0);

/* присвоить имя конечной точке */

int Bind{)

struct t bind *bind;



1 ... 64 65 66 [ 67 ] 68 69 70 ... 98

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