Электронная библиотека книг Александра Фролова и Григория Фролова.
Shop2You.ru Создайте свой интернет-магазин
Библиотека
Братьев
Фроловых
Локальные сети персональных компьютеров. Использование протоколов IPX, SPX, NETBIOS
© Александр Фролов, Григорий Фролов
Том 4, М.: Диалог-МИФИ, 1993, 160 стр.

[Назад] [Содеожание] [Дальше]

3.3. Функции SPX

3.3.1. Инициализация SPX

SPXCheckInstallation

На входе: BX = 10h.
AL = 00h.
На выходе: AL = Код завершения:
00h - SPX не установлен;
FFh - SPX установлен.
BH = Верхний (major) номер версии SPX.
BL = Нижний (minor) номер версии SPX.
CX = Максимальное количество каналов SPX, поддерживаемых драйвером SPX.
DX = Количество доступных каналов SPX.

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

3.3.2. Образование канала связи

SPXListenForConnection

На входе: BX = 12h.
AL = Счетчик повторов попыток создать канал связи.
AH = Флаг включения системы периодической проверки связи (Watchdog Supervision Required Flag).
ES:SI = Указатель на блок ECB.
На выходе: Регистры не используются.

Эта функция используется в паре с функцией SPXEstablishConnection для образования канала связи.

Программа-сервер вызывает SPXListenForConnection, передавая ей адрес блока ECB. Этот блок будет использован для образования канала связи. Когда программа-клиент вызовет функцию SPXEstablishConnection, произойдет образование канала связи и в поле InUse блока ECB будет записано нулевое значение. Будет также вызвана соответствующая программа ESR, если задан ее адрес.

В блоке ECB необходимо определить значение поля ESRAddress и указать номер сокета. Для каждого сокета вы можете образовать несколько каналов.

Блок ECB, адрес которого задан в регистрах ES:SI, ставится драйвером SPX во внутреннюю очередь блоков ECB, ожидающих прихода пакетов от функций SPXEstablishConnection, выдаваемых другими станциями, желающими образовать канал связи.

После образования канала связи, когда в поле InUse будет записано нулевое значение, поле CCode блока ECB будет содержать код завершения:

00 канал связи создан, ошибок нет;
FFh указанный в ECB сокет не был открыт;
FCh запрос SPXListenForConnection был отменен функциями IPXCancelEvent или IPXCloseSocket (ESR не вызывается);
EFh переполнилась внутренняя таблица номеров каналов связи; до тех пор, пока какой-нибудь канал не будет закрыт, вы не сможете образовать новые каналы.

Перед вызовом функции SPXListenForConnection программа должна выделить хотя бы один ECB для приема SPX-пакета. Это нужно сделать при помощи функции SPXListenForSequencedPacket (см. ниже описание функции).

Вам также надо задать в регистре AL cчетчик повторов попыток создания канала связи и в регистре AH - флаг включения системы периодической проверки связи. Вы можете задать от 1 до 255 попыток или использовать значение по умолчанию, если запишете в регистр AL нулевое значение.

Если в регистр AH будет записано ненулевое значение, драйвер SPX будет периодически проверять работоспособность канала связи, передавая специальные тестовые пакеты. Если канал вдруг перестает работать, он разрывается и в ECB, подготовленный для приема пакетов функцией SPXListenForSequencedPacket, в поле InUse проставляется нулевое значение. Поле CCode при этом будет содержать код ошибки EDh, а номер "испорченного" канала будет записан в первых двух байтах поля IPXWorkspace блока ECB.

SPXEstablishConnection

На входе: BX = 11h.
AL = Счетчик повторов попыток создать канал связи.
AH = Флаг включения системы периодической проверки связи (Watchdog Supervision Required Flag).
ES:SI = Указатель на блок ECB.
На выходе: AL = Промежуточный код завершения:
00h - выполняется попытка создать канал;
FFh - указанный в блоке ECB сокет закрыт;
FDh - сбойный пакет: либо счетчик фрагментов не равен 1, либо размер фрагмента не равен 42;
EFh - переполнение локальной таблицы номеров каналов связи.
DX = Присвоенный номер канала.

Функция устанавливает канал связи с программой, предварительно вызвавшей функцию SPXListenForConnection.

Для функции необходимо подготовить блок ECB и пакет в формате SPX, состоящий из одного заголовка. В блоке ECB необходимо заполнить поля ESRAddress, Socket, счетчик количества фрагментов (нужен один фрагмент) и указатель на фрагмент размером 42 байта. В заголовке SPX-пакета необходимо заполнить поля DestNetwork, DestNode, DestSocket.

Кроме того, перед вызовом функции SPXListenForConnection программа должна выделить хотя бы один ECB для приема SPX-пакета. Это нужно сделать при помощи функции SPXListenForSequencedPacket (см. ниже описание функции).

Канал создается в два приема.

На первом этапе проверяется возможность образования канала - проверяется наличие свободного места в таблице номеров каналов, проверяется таблица сокетов, размер пакета. Если все хорошо, с целью попытки создать канал удаленному партнеру посылается пакет, после чего функция возвращает управление вызвавшей ее программе. Регистр AL при этом содержит промежуточный код завершения. Если этот код равен нулю, можно переходить к ожиданию приема ответного пакета от партнера по созданию канала. Регистр DX при этом содержит номер присвоенного канала.

Если партнер отвечает соответствующим образом, в поле InUse блока ECB устанавливается нулевое значение. Если при этом в поле CCode также находится нулевое значение, канал считается созданным.

Номер канала удаленного партнера, который вы будете использовать для передачи ему пакетов функцией SPXSendSequencedPacket, находится в поле SourceConnID блока ECB. Сохраните его для дальнейшего использования.

Если по каким-либо причинам канал создать не удалось, в поле CCode будет записан код ошибки:

00h канал связи создан, ошибок нет;
FCh запрос SPXListenForConnection был отменен функциями IPXCancelEvent или IPXCloseSocket (ESR не вызывается);
FDh сбойный пакет: либо счетчик фрагментов не равен единице, либо размер фрагмента не равен 42;
FFh указанный в ECB сокет не был открыт;
EFh переполнилась внутренняя таблица номеров каналов связи; до тех пор, пока какой-нибудь канал не будет закрыт, вы не сможете образовать новые каналы;
EDh адресат не отвечает или сообщает, что он не может создать канал; этот код может возникнуть либо как результат неисправности сетевого аппаратного обеспечения, либо если функция SPXEstablishConnection была отменена при помощи функции SPXAbortConnection.

Обратим ваше внимание на то, что для отмены создания канала необхо-
димо пользоваться специально предназначенной для этого функцией SPXAbortConnection, а не функцией IPXCancelEvent.

3.3.3. Прием и передача пакетов

SPXListenForSequencedPacket

На входе: BX = 17h.
ES:SI = Указатель на блок ECB.
На выходе: Регистры не используются.

Функция обеспечивает прием пакетов средствами протокола SPX. При этом она ставит блок ECB, адрес которого передается через регистры ES:SI, в очередь на прием, после чего немедленно возвращает управление вызвавшей программе.

После того как пакет будет принят, в поле InUse блока ECB устанавливается нулевое значение, а в поле CCode - код завершения:

00h пакет принят без ошибок;
FCh запрос SPXListenForSequencedPacket был отменен функциями IPXCancelEvent или IPXCloseSocket (ESR не вызывается);
FDh переполнение пакета - принятый пакет имеет длину, которая превосходит размер буферов, указанных в дескрипторах фрагментов;
EDh система периодической проверки связи обнаружила разрыв канала, номер разрушенного канала записан в первых двух байтах поля IPXWorkspace блока ECB;
FFh указанный в ECB сокет не был открыт.

Перед вызовом функции необходимо заполнить в ECB поля ESRAddress, Socket, счетчик фрагментов и дескрипторы фрагментов. При этом первый фрагмент передаваемого пакета должен иметь длину не менее 42 байт - это буфер для приема стандартного заголовка SPX-пакета. Необходимо также открыть используемый сокет при помощи функции IPXOpenSocket.

Обычно для приема пакетов используется несколько блоков ECB. Все они по-
следовательно ставятся в очередь функцией SPXListenForSequencedPacket. Для приема пакета драйвером SPX может быть использован любой свободный блок ECB. Не гарантируется, что блоки ECB будут использованы именно в том порядке, в котором они ставились в очередь функцией SPXListenForSequencedPacket.

Если принимается системный пакет, использованный блок ECB автоматически возвращается в очередь для приема пакетов.

Так как для обработки системных пакетов протокол гарантированной доставки SPX использует те же блоки ECB, что и для приема прикладных пакетов, ваша программа должна обеспечить достаточное количество блоков ECB в очереди на прием пакетов.

Если принимается пакет, у которого в заголовке в поле DataStreamType находится значение FEh, это означает, что передающая программа собирается завершить передачу и закрыть канал. При этом все блоки ECB, стоящие в очередь на передачу пакетов (в которую они ставятся функцией SPXSendSequencedPacket, описанной ниже), отмечаются нулевым значением в поле InUse и соответствующим кодом завершения в поле CCode.

Программа может отменить ожидание завершения приема пакета для блока ECB при помощи функции IPXCancelEvent, при этом она должна заново проинициализировать поле ESRAddress перед повторным использованием этого блока ECB.

SPXSendSequencedPacket

На входе: BX = 16h.
ES:SI = Указатель на блок ECB
DX = Номер канала связи.
На выходе: --- Регистры не используются.

Функция ставит блок ECB, адрес которого указан в регистрах ES:SI, в очередь на передачу, после чего немедленно возвращает управление вызвавшей программе.

Перед вызовом функции программа должна заполнить поле ESRAddress, счетчик фрагментов и дескрипторы фрагментов блока ECB, а также бит End-Of-Message в поле ConnControl и поле DataStreamType в заголовке передаваемого пакета. Разумеется, заголовок должен иметь длину 42 байта.

В регистр DX необходимо загрузить номер канала, используемый партнером.

В отличие от средств передачи пакета протокола IPX успешное завершение передачи пакета, инициированной функцией SPXSendSequencedPacket, гарантирует доставку пакета партнеру. Если партнер не успевает принимать передаваемые пакеты, они ставятся в очередь на передачу, чем обеспечивается правильная последовательность доставки пакетов.

После завершения передачи пакета поле InUse блока ECB имеет нулевое значение. Если определена программа ESR, она вызывается. В поле CCode находится код завершения:

00h пакет был передан и успешно принят партнером;
FCh указанный в ECB сокет был закрыт, программа ESR не вызывается;
FDh сбойный пакет: либо счетчик фрагментов равен нулю, либо размер первого фрагмента меньше 42 байт, либо размер всего пакета больше 576 байт;
EEh неправильное значение в регистре DX;
EDh либо система периодической проверки связи обнаружила разрыв канала, либо канал был уничтожен функцией SPXAbortConnection (номер разрушенного канала записан в первых двух байтах поля IPXWorkspace блока ECB);
ECh удаленный партнер закрыл канал без подтверждения приема этого пакета, при этом SPX не может гарантировать, что переданный пакет был успешно принят партнером перед тем, как канал был закрыт.

Для отмены передачи пакета нельзя использовать функцию IPXCancelEvent. Вместо нее необходимо использовать функцию SPXAbortConnection.

[Назад] [Содеожание] [Дальше]