static class Utilities { /// <summary> /// Считывает из потока максимально возможное число байт. /// </summary> /// <remarks>Полезно для считывания из сети (сервер высылает /// ответ, после чего закрывает соединение).</remarks> /// <param name="stream">Поток для чтения.</param> /// <returns>Массив считанных байт.</returns> public static byte[] ReadToEnd ( this Stream stream ) { MemoryStream result = new MemoryStream(); while (true) { byte[] buffer = new byte[10 * 1024]; int read = stream.Read(buffer, 0, buffer.Length); if (read <= 0) { break; } result.Write(buffer, 0, read); } return result.ToArray(); } }Метод, конечно же, реализован далеко не оптимально. Например, при получении большого пакета с сервера происходит многократное перераспределение и копирование блоков памяти, что отрицательно сказывается на быстродействии. К тому же потребность в памяти составляет до 2 * (размер принимаемого пакета), это становится критичным при написании мобильных и встраиваемых клиентов ИРБИС.
using System; using System.Diagnostics; using System.Linq; using System.Runtime.InteropServices; namespace KillIrbis { class Program { private const int WM_QUIT = 0x0012; private const string DefaultProcessName = "irbis_server"; [DllImport ( "User32.dll", SetLastError = false )] private static extern int PostThreadMessage ( int threadId, int msg, int wParam, IntPtr lParam ); private static bool StopProcess ( Process process ) { try { foreach ( ProcessThread thread in process.Threads ) { PostThreadMessage ( thread.Id, WM_QUIT, 0, IntPtr.Zero ); } } catch ( Exception exception ) { Debug.WriteLine ( exception ); return false; } return true; } private static bool StopProcess ( string processName ) { bool result = false; Process[] processes = Process .GetProcessesByName ( processName ); if ( processes.Length != 0 ) { result = processes.All(StopProcess); } return result; } static void Main ( string[] args ) { if ( args.Length > 1 ) { Console.WriteLine ( "USAGE: KillIrbis [processName]" ); return; } string processName = DefaultProcessName; if ( args.Length == 1 ) { processName = args [ 0 ]; } Console.Write ( "Trying to stop {0}: ", processName ); bool result = StopProcess ( processName ); Console.WriteLine( result ? "success" : "failure" ); } } }Для тех, кому не хочется компилировать программу самостоятельно, прилагается её исполняемый файл.
@echo off rem Устанавливаем пути до локального сервера ИРБИС set IRBIS=D:\IRBIS64 set DATAI=%IRBIS%\DATAI rem Восстанавливаем базу в известное состояние rem Предполагается, что предварительно база была сохранена в папку SAVE copy /B /Y %DATAI%\SAVE\*.* %DATAI%\IBIS rem Запускаем сервер start %IRBIS%\irbis_server rem Здесь помещаем вызов своего клиента IrbisPing "host=127.0.0.1;port=6666;user=1;password=1;db=IBIS;arm=A;debug=clientdump.txt" rem Завершаем сервер KillIrbis rem Ожидаем пользователя pauseОтладка взаимодействия самописного клиента с сервером становится гораздо более комфортной.
int min = 100000; // Это примерные значения, int max = 900000; // можете использовать другие Random rand = new Random(); int identifier = rand.nextInt(max - min) + min;> Посмотреть бы исходники сервера, чтобы понять,
64.2008.1 1 100000А потом перешёл на четырёхстрочный формат "Организация - Версия - Активные подключения - Лимит подключений". Просто поддерживайте оба варианта, и проблема решена.
-------------------------------------------------------------------------------------------- | Код | Описание | Примечания | -------------------------------------------------------------------------------------------- | 0 | Нормальное завершение | | | -100 | Заданный MFN вне пределов БД | | | -101 | Ошибочный размер полки | в IRBIS64_CLIENT.DLL | | -102 | Ошибочный номер полки | в IRBIS64_CLIENT.DLL | | -140 | MFN вне пределов БД | | | -141 | Ошибка чтения | | | -200 | Указанное поле отсутствует | в IRBIS64_CLIENT.DLL | | -201 | Предыдущая версия записи отсутствует | | | -202 | Заданный термин не найден (термин не существует) | | | -203 | Последний термин в списке | | | -204 | Первый термин в списке | | | -300 | База данных монопольно заблокирована | | | -301 | База данных монопольно заблокирована | | | -400 | Ошибка при открытии файлов MST или XRF | | | | (ошибка файла данных) | | | -401 | Ошибка при открытии файлов IFP | | | | (ошибка файла индекса) | | | -402 | Ошибка при записи | | | -403 | Ошибка при актуализации | | | -600 | Запись логически удалена | | | -601 | Запись физически удалена | | | -602 | Запись заблокирована на ввод | | | -603 | Запись логически удалена | в IRBIS64_CLIENT.DLL | | -605 | Запись физически удалена | в IRBIS64_CLIENT.DLL | | -607 | Ошибка autoin.gbl | | | -608 | Ошибка версии записи | | | -700 | Ошибка создания резервной копии | | | -701 | Ошибка восстановления из резервной копии | | | -702 | Ошибка сортировки | | | -703 | Ошибочный термин | | | -704 | Ошибка создания словаря | | | -705 | Ошибка загрузки словаря | | | -800 | Ошибка в параметрах глобальной корректировки | | | -801 | ERR_GBL_REP | | | -802 | ERR_GBL_MET | | | -1111 | Ошибка исполнения сервера (SERVER_EXECUTE_ERROR) | | | -2222 | Ошибка в протоколе (WRONG_PROTOCOL) | | | -3333 | Незарегистрированный клиент | | | | (ошибка входа на сервер) (клиент не в списке) | | | -3334 | Клиент не выполнил вход на сервер | | | | (клиент не используется) | | | -3335 | Неправильный уникальный идентификатор клиента | | | -3336 | Нет доступа к командам АРМ | Михайленко утверждает: | | | | «список клиентов перегружен» | | -3337 | Клиент уже зарегистрирован | | | -3338 | Недопустимый клиент | | | -4444 | Неверный пароль | | | -5555 | Файл не существует | | | -6666 | Сервер перегружен. Достигнуто максимальное число | | | | потоков обработки | | | -7777 | Не удалось запустить/прервать поток | | | | администратора (ошибка процесса) | | | -8888 | Общая ошибка | | --------------------------------------------------------------------------------------------