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


Листинг 3



Листинг 3

Просмотр списка активных серверов и вывод в стандарт- // ный поток имен и другой информации об активных серверах // Файл slist!\slist.cpp // // (C) A. Frolov, 1993 // ================================================================ #include <stdlib.h> #include <stdio.h> #include <mem.h> #include <string.h> #include <dos.h> #include <direct.h> #include "sap.hpp" void main(void) { SLIST *ServerList; int ccode = 0; printf("\n*SLIST!*, v.1.0, (C) Фролов А.В., 1993\n"); // Создаем объект класса SLIST. Конструктор этого объекта // получает всю необходимую информацию о серверах и // записывает ее в область данных объекта ServerList = new SLIST(GENERAL_SERVICE); // Если при создании объекта были ошибки, завершаем // выполнение программы ccode = ServerList->Error(); if(ccode) { printf("Ошибка %d\n", ccode); return; } // Выводим список серверов printf("\nОбнаружены серверы:\n"); printf( "---------------------------------------------" "------------------------------\n"); ServerList->PrintServersName(); printf( "---------------------------------------------" "------------------------------\n"); }

Файл slist.cpp содержит определения функций-членов класса SLIST (листинг 4).

Конструктор SLIST() проверяет наличие сетевой оболочки, проверяет и запоминает тип запроса (получить сведения о ближайшем сервере или о всех серверах сети) и запоминает его. Затем конструктор инициализирует драйвер протокола IPX и открывает динамический короткоживущий сокет для работы с протоколом SAP. Далее в цикле создаются блоки ECB и ставятся в очередь на прием пакетов. Эти блоки ECB будут использованы для приема SAP-пакетов. После подготовки ECB конструктор посылает пакет запроса, ожидает примерно одну секунду и при помощи функций SLIST::GetServersName() и SLIST::GetServersInfo() получает и запоминает имена серверов и другую информацию.

Для работы с IPX-пакетами мы использовали функции из библиотеки NetWare C Interface. Назначение этих функций вам будет понятно из их названия, если вы прочитали предыдущий том "Библиотеки системного программиста".

Функция IPXInitialize() проверяет наличие драйвера протокола IPX и выполняет все инициализирующие действия, необходимые для использования протокола IPX.

Функция IPXOpenSocket() предназначена для открытия сокета. Первый параметр функции - указатель на переменную типа WORD, содержащую значение открываемого сокета или ноль, если надо получить динамический сокет. Байты в этой переменной расположены в обратном порядке, т. е. старший байт расположен по младшему адресу. Второй параметр функции IPXOpenSocket() определяет тип открываемого сокета - долгоживущий или короткоживущий. В нашем случае мы открываем динамический короткоживущий сокет.

После открытия сокета конструктор с помощью функции SLIST::ReceiveSAPPacket() подготавливает массив блоков ECB для приема ответных пакетов и, вызывая функцию IPXListenForPacket(), ставит эти блоки в очередь на прием. Функция IPXListenForPacket() имеет в качестве единственного параметра указатель на блок ECB.

Далее конструктор вызывает функцию SLIST::SendSAPPacket(), которая подготавливает блок ECB и заголовок IPX-пакета для SAP-запроса. При этом с помощью функции IPXGetInternetworkAddress() программа определяет свой собственный сетевой адрес. Функция IPXGetInternetworkAddress() имеет в качестве параметра указатель на структуру, в которую будет записан номер сети и сетевой адрес узла в сети.

Подготовив пакет, функция SLIST::SendSAPPacket() ставит его в очередь на передачу при помощи функции IPXSendPacket(), передавая ей в качестве параметра указатель на соответствующий блок ECB.

Когда пакет будет передан, конструктор ждет примерно одну секунду. В течение этого времени приходят ответные пакеты от серверов. После ожидания вызываются функции SLIST::GetServersName() и SLIST::GetServersInfo(), получающие соответсвенно имена серверов и дополнительную информацию.

Функция SLIST::GetServersName() переписывает имена откликнувшихся на запрос серверов из принятых SAP-пакетов во внутренний массив объекта класса SLIST.

Функция SLIST::GetServersInfo() выполняет более сложные действия.

Вначале с помощью функций GetPrimaryConnectionID() и GetDefaultConnectionID() она получает номера каналов первичного и текущего серверов, записывая их во внутренние переменные объекта класса SLIST. Затем запускается цикл по всем обнаруженным в сети серверам.

Внутри этого цикла для каждого сервера функция получает его номер канала при помощи функции GetConnectionID(). Если канала нет, рабочая станция создает его, подключаясь к серверу. Для подключения используется функция AttachToFileServer().

Затем сервер делается предпочтительным, для чего вызывается функция SetPreferredConnectionID(). Теперь все запросы будут идти к предпочтительному серверу. Внутри цикла мы по очереди будем делать все имеющиеся серверы предпочтительными и, направляя запросы, получать от серверов интересующую нас информацию.

Далее функция SLIST::GetServersInfo() вызывает функцию GetServerInformation(), которая записывает сведения о сервере в структуру ServerInfo. Первый параметр функции GetServerInformation() задает размер этой структуры, а второй является указателем на нее.

Перед возвратом функция SLIST::GetServersInfo() пытается получить серийный номер операционной системы Novell NetWare, работающей на предпочтительном файл-сервере, вызывая функцию GetNetworkSerialNumber(). Этой функции в качестве первого параметра необходимо передать указатель на переменную типа long, в качестве второго - указатель на переменную типа WORD. В первую переменную функция запишет серийный номер операционной системы, во вторую - серийный номер приложения, работающего на файл-сервере.

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

Функция SLIST::PrintServersName() в цикле для всех обнаруженных серверов выводит в стандартный поток вывода имя сервера, напротив которого указывается, является ли он первичным (Primary) или текущим (Default). Затем выводится версия Novell NetWare, взятая из полей netwareVersion и netwareSubVersion структуры ServerInfo. Для подключенных серверов выводится серийный номер и номер приложения.

Далее для всех серверов выводится номер канала, используемого сервером и записанного ранее в массив ConnID[].

После этого для каждого сервера выводится содержимое полей maxConnectionsSupported и connectionsInUse структуры ServerInfo, которые содержат максимальное количество каналов для сервера и количество каналов, используемых в данный момент.

Перед окончанием работы программы вызывается деструктор, который отменяет все ожидающие приема блоки ECB и закрывает динамический сокет. Для отмены блоков ECB используется функция IPXCancelEvent(), которой в качестве параметра передается указатель на отменяемый блок ECB. Сокет закрывается при помощи функции IPXCloseSocket(). Номер закрываемого сокета передается этой функции в качестве параметра. // ===================================================









- Начало -  - Назад -  - Вперед -