Электронная библиотека книг Александра Фролова и Григория Фролова.
Shop2You.ru Создайте свой интернет-магазин
Библиотека
Братьев
Фроловых

Локальные сети персональных компьютеров. Работа с сервером Novell NetWare

© Александр Фролов, Григорий Фролов
Том 4, М.: Диалог-МИФИ, 1993, 168 стр.

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

7.4. Передача сообщений пользователям

Для передачи сообщения другим пользователям предназначена функция SendBroadcastMessage():

int SendBroadcastMessage(char *Message, WORD *ConnectionList,
       BYTE *ResultList, WORD ConnectionCount);


Параметр Message задает адрес текстовой строки, содержащей сообщение. Размер этой строки не должен превышать 56 байт (включая двоичный ноль, закрывающий строку).

Параметр ConnectionList - указатель на массив слов, содержащий номера каналов, используемых файл-сервером для связи с рабочими станциями. Размер этого массива определяется параметром ConnectionCount.

Параметр ResultList - массив байт, в котором для каждой станции отражается результат посылки сообщения:

0x00 Сообщение передано успешно
0xFC Сообщение не передано, так как буфер сообщения для данной станции уже содержит сообщение, которое еще не было принято станцией
0xFD Соответствующий номер канала задан неправильно
0xFF Станция заблокировала прием сообщения, установив соответствующий режим приема сообщений. Этот код ошибки может появиться и в том случае, если заданный номер канала не используется

Функция возвращает 0 при успешном завершении или код ошибки:

Код ошибки Значение
0xFE Ошибка ввода/вывода или нехватка памяти на сервере

Вместо функции SendBroadcastMessage() можно использовать функцию E1h прерывания INT 21h:

На входе: AH = E1h;
DS:SI = Адрес буфера запроса;
ES:DI = Адрес буфера ответа.
На выходе: AL = Код ошибки или 0, если операция завершилась без ошибок.

Буфер запроса:

struct REQUEST {
        WORD    PacketLength;        // размер пакета запроса
        BYTE    Function;            // должно быть равно 0
        BYTE    ConnectionCount;     // количество станций
        BYTE    ConnectionList[ConnectionCount];// список станций
        BYTE    MessageLength;       // длина сообщения
        BYTE    Message[MessageLength]; // сообщение
};


Буфер ответа:

struct REPLAY {
        WORD    PacketLength;        // размер пакета
        BYTE    ConnectionCount;     // количество станций
        BYTE    ResultList[ConnectionCount];// результат
};


7.4.1. Программа MSGSEND

Программа MSGSEND (листинг 28) передает сообщение, заданное в качестве параметра, всем пользователям, подключенным к файл-серверу. Перед посылкой сообщения она с помощью функции BroadcastToConsole() выводит текстовую строку на консоль файл-сервера и записывает эту же строку в системный журнал net$log.msg, вызывая функцию LogNetworkMessage().

Для получения списка пользователей программа использует функцию GetConnectionInformation(). Эта функция возвращает информацию о пользователе, подключенном к файл-серверу, по номеру канала. Каналы нумеруются начиная с первого. Максимальное количество каналов определяется версией операционной системы, его можно определить при помощи функции GetServerInformation().

Сканируя все каналы, программа подготавливает массив номеров каналов ConnectionList[] для функции SendBroadcastMessage(), которая и выполняет рассылку сообщений.

// ===================================================
// Листинг 28. Посылка сообщения станциям
// Файл msgsend\msgsend.cpp
//
// (C) A. Frolov, 1993
// ===================================================

#include <stdlib.h>
#include <stdio.h>

#define WORD unsigned int
#define BYTE unsigned char

typedef struct {
         char    serverName[48];
         BYTE    netwareVersion;
         BYTE    netwareSubVersion;
         WORD    maxConnectionsSupported;
         WORD    connectionsInUse;
         WORD    maxVolumesSupported;
         BYTE    revisionLevel;
         BYTE    SFTLevel;
         BYTE    TTSLevel;
         WORD    peakConnectionsUsed;
         BYTE    accountingVersion;
         BYTE    VAPversion;
         BYTE    queingVersion;
         BYTE    printServerVersion;
         BYTE    virtualConsoleVersion;
         BYTE    securityRestrictionLevel;
         BYTE    internetBridgeSupport;
} FILE_SERV_INFO;

extern "C" int GetNetWareShellVersion(char *,char *, char *);
extern "C" int BroadcastToConsole(char *);
extern "C" int SendBroadcastMessage(char*, WORD*, BYTE*, WORD);
extern "C" int LogNetworkMessage(char*);
extern "C" void GetServerInformation(int, FILE_SERV_INFO*);
extern "C" int GetConnectionInformation(WORD, char *, WORD *,
                                                long *, BYTE *);

void main(int argc, char *argv[]) {

        char MajorVersion=0;
        char MinorVersion=0;
        char Revision=0;

        long ObjectID;
        char ObjectName[48];
        WORD ObjectType;
        BYTE LoginTime;
        FILE_SERV_INFO ServerInfo;
        int MaxUsers;

        WORD ConnectionList[250];
        BYTE ResultList[250];
        WORD ConnectionCount;

        printf("\n*MSGSEND* (C) Frolov A., 1993\n");

        if(argc < 2) {
                printf("Введите сообщение в качестве параметра\n");
                return;
        }

// Проверяем присутствие сетевой оболочки

        asm push si
        GetNetWareShellVersion(&MajorVersion,
                        &MinorVersion, &Revision);
        asm pop si

        if(MajorVersion == 0) {
                printf("\nОболочка NetWare не загружена\n");
                return;
        }

// Выводим сообщение на консоль файл-сервера и
// записываем его в журнал

        BroadcastToConsole("*MSGSEND* (C) Frolov A., 1993");
        LogNetworkMessage("*MSGSEND* (C) Frolov A., 1993");

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

        GetServerInformation(sizeof(ServerInfo), &ServerInfo);

// Запоминаем максимальное количество пользователей

        MaxUsers = ServerInfo.maxConnectionsSupported;
        printf("Сервер %s, версия на %d пользователей\n",
                ServerInfo.serverName,  MaxUsers);

// Цикл посылки сообщений. Подсчитываем количество используемых
// каналов и для каждого канала заполняем массив ConnectionList[]

        printf("\nСообщение посылается пользователям:\n");

        ConnectionCount = 0;

        for(int i=1, j=0; i <= MaxUsers; i++) {

// Получаем информацию о канале

                GetConnectionInformation(i, ObjectName, &ObjectType,
                                &ObjectID, &LoginTime);

// Если есть имя объекта, выводим его на экран

                if(ObjectName[0] != '\0') {
                        printf("%s\n", ObjectName);

// Записываем номер канала в массив

                        ConnectionList[j++] = i;
                        ConnectionCount += 1;
                }
        }

// Посылаем сообщение обнаруженным пользователям

        SendBroadcastMessage(argv[1],
                ConnectionList, ResultList, ConnectionCount);
}


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