Базы данныхИнтернетКомпьютерыОперационные системыПрограммированиеСетиСвязьРазное
Поиск по сайту:
Подпишись на рассылку:

Назад в раздел

Опыт разработки распределенной библиотечной системы на основе Internet

Опыт разработки распределенной библиотечной системы на основе Internet

В.Филиппов, К.Кузяков, ВЦ РАН

Введение

Информационная система LIBWEB, предполагающая интеграцию информационных ресурсов ведущих библиотек России на основе World Wide Web (WWW) технологии, широко используемой в Internet, будет направлена на удовлетворение информационных и библиографических потребностей специалистов, ведущих фундаментальные исследования в основных областях знаний. Число пользователей системы, совпадающее с числом специалистов, ведущих фундаментальные исследования, по данным Российского Фонда Фундаментальных Исследований, оценивается в настоящее время в несколько десятков тысяч человек.
Информационная система LIBWEB будет представлять собой информационно-поисковую библиографическую систему; количество выходных форм - несколько десятков (во всех основных библиографических стандартах); источник данных в информационной системе - библиографические описания монографий, сборников, журналов и другой печатной продукции; для реализации будут параллельно использоваться СУБД ORACLE; режим поиска будет организован на основе стандарта языка запросов SQL 2, путем заполнения соответствующих форм запроса с использованием основных логических операций.

Интеграция СУБД в глобальную сеть Internet

Интеграция информационных ресурсов библиотеки организована путем создания на основе WWW (World Wide Web) - технологии серверов в основных библиотеках и информационных центрах страны с обеспечением средств доступа к ним на основе протокола TCP/IP.
Таким образом, одной из задач проекта является обеспечение стыковки базы данных СУБД ORACLE с Internet протоколами и разработка удобного пользовательского интерфейса позволяющего осуществлять поиск интересующей пользователя литературы. WWW - это гипертекстовая система, использующая для общения клиента с сервером собственный протокол HTTP (HyperText Transfer Protocol), а также поддерживающий массу различных протоколов обмена приложений Internet. Для создания и использования гипертекстовых документов определен язык HTML (HyperText Markup Language). Для указания ресурсов используется технология URL (Universal Resource Locator). С помощью данной технологии реализуется взаимодействие WWW- сервера с базами данных ORACLE. Суть такого взаимодействия заключается в том, что программа-сервер (Alibaba) WWW способна организовать взаимодействие с классом программ класса CGI (Common Gateway Interface). Один из вариантов использования CGI - исполнение SQL- запросов к базе данных.
Целью работы является создание программного комплекса, предоставляющего удаленному пользователю, связавшемуся с WWW сервером библиотечной системы, удобного интерфейса для формирования запросов для поиска литературы в базе данных, осуществление этого поиска и выдача результатов в удобном для пользователя представлении.
Программа должна перефразировать запрос пользователя в SQL запрос к базе данных и получать результаты его выполнения, а также диагностировать возникающие ошибки.
Инструментальными средствами решения этой задачи являются C, SQL и HTML, а также пакет разработчика ODBC SDK.
Обмен данными производится на основе архитектуры клиент-сервер. Для обмена данными используются документы MIME (Multipurpose Internet Mail Extensions) стандарта, который включает в себя описание различных типов документов от простого текста до анимации. Интерпретация полученных документов возлагается на средства просмотра документов работающие на стороне клиента такие, как Modzilla, Netscape, Mozaic и им подобные, объединяемые названием WWW browsers.
WWW сервер постоянно находится в режиме ожидания запросов на соединение от удаленных пользователей. После установления сеанса связи с клиентским приложением просмотра документов клиенту пересылается либо указанный им документ, либо стандартный документ- заставка (home page) сервера.

Стандартные интерфейсы WWW серверов

Для организации передачи данных из HTML документа технология WWW серверов использует CGI интерфейс обмена данными между сервером и приложением-обработчиком(в Windows подобных операционных системах это Windows CGI интерфейс). При переходе по гиперсвязи из гипертекстового HTML документа адрес гиперузла вместе с необходимой дополнительной информацией передается от клиента к WWW серверу. WWW сервер анализирует тип документа , который находится в указанном узле и либо сразу после некоторой обработки передает документ клиенту, либо, если в узле находится документ с MIME типом "application/...", то запускает это приложение на исполнение и затем возвращает результаты работы этого приложения клиенту. При запуске приложения приложению передается информация о клиенте и информация, получаемая из HTML документа клиента, например из объектов диалога, обозначаемых тэгом FORM.
Операционная система Windows не имеет собственного командного интерпретатора, поэтому обработчик должен быть исполняемой программы. Для упрощения интерфейса и минимизации программирования используется интерфейс обмена данными через файлы, что является подходом противоположным подходу DDE. Выбор такого способа обмена объясняется необходимостью обеспечения одновременного подключения к серверу большого количества клиентских программ при минимальных ограничениях на количество доступной оперативной памяти. Данные, необходимые обработчику помещаются в специальный входной файл, результаты выполнения записываются в специальный выходной файл, который затем считывается WWW сервером.
Информация в выходном файле начинается с указания MIME типа, которому она соответствует.
WWW сервер использует сервис WinExec() для запуска программы-обработчика. Сервер поддерживает синхронизацию с обработчиком, несмотря на то, что WinExec() запускает приложения асинхронно, таким образом сервер может определить момент окончания исполнения обработчика.
Сервер запускает обработчик с помощью WinExec() с командной строкой следующего вида:
обработчик файл-данных-CGI файл-контекста выходной-файл URL-аргументы, где файл-данных-CGI - файл, в который сервер записывает служебную информацию, файл-контекста - файл, в который сервер записывает данные, введенные пользователем в HTML документ, выходной-файл - файл, в который обработчик должен записать результаты работы, URL-аргументы - все, что следует за '?' в URL запросе.
Windows-сервер передает данные программе обработчику через Windows "private profile" файл в формате пар ключ-значение.
Файл CGI данных содержит следующие разделы: [CGI] [Accept] [System] [Extra Headers] [Form Literal] [Form External] [Form Huge]

Технология ODBC организации доступа к базам данных

ODBC (Open Database Connectivity) является средством, позволившим унифицировать организацию взаимодействия с различными базами данных. Для этого доступ к базе данных осуществляется при помощи специального ODBC драйвера, который транслирует запросы к базе данных со стандарта языка SQL на язык, поддерживаемый конкретной системой управления базами данных.
Для установления соединения с базой данных технология ODBC использует ODBC драйверы, источники данных (data sources), которые позволяют настроится на сеанс конкретного пользователя системы управления базой данных. Для этого источник содержит системное имя пользователя и его пароля, а также, при необходимости, другую информацию, требуемую для присоединения к базе данных.
ODBC драйвер представляет собой динамическую библиотеку (DLL), которая может использоваться приложением для получения доступа к конкретному источнику данных. Каждой системе управления базами данных необходим свой ODBC драйвер.
Источник данных включает в себя данные, к которым пользователь хочет иметь доступ , и информацию, необходимую для того, чтобы получить эти данные.
Система ODBC также включает в себя ODBC менеджер драйверов и транслятор. Менеджер драйверов - это динамическая библиотека, которая выполняет ряд управляющих и контролирующих функций, а также предоставляет доступ к ODBC драйверам. Транслятор - это динамическая библиотека, которая транслируют все данные, циркулирующие между базой данных и источником данных. Обычно транслятор занимается переводом символьных данных в другую кодировку, хотя также может совершать кодирование/декодирование или сжатие/обратное восстановление данных.
Взаимодействие с базой данных осуществляется при помощи набора системных вызовов, которые по функциональной нагрузке можно разделить на следующие группы:
Установление соединения с источником данных. Функции данной группы позволяют произвести необходимую инициализацию переменных для настройки на конкретное соединение, произвести соединение с ODBC драйвером и получить информацию о параметрах, требуемых для соединения с базой данных. Получение информации об имеющихся ODBC драйверах и источниках данных. Эти функции используются для получения перечня доступных ODBC драйверов и источников данных, а также их атрибутов и поддерживаемых драйверами функций и типах данных. Установка и контроль установленных значений ODBC драйвера. Функции этой группы позволяют редактировать атрибуты соединения и конкретного запроса к базе данных. Подготовка SQL запроса. Эти функции позволяют подготовить SQL запрос и задать его параметры, а также определить курсор для данного запроса и установить значения опций, управляющих поведением курсора. Исполнение SQL запроса. Эта группа вызовов позволяет выполнять ранее подготовленные или вновь создаваемые SQL запросы и управляет передачей параметров в SQL запросы. Получение результатов и информации о структуре результирующего множества. В эту группу объединены системные вызовы, позволяющие получать информацию об атрибутах результирующего множества, ассоциировать результирующее множество с набором массивов, организовать циклическое получение результатов по мере их поступление в результирующее множество и получить параметры диапазона , на который подействовал модифицирующий базу запрос. Получение информации о базе данных. Эти функции позволяют получать данные о структуре базы данных: о таблицах и их атрибутах, первичных и внешних ключах, наборе хранимых процедур и общую статистику. Завершение выполнения запроса и разрыв соединения.

Стандарт DDE межпроцессного взаимодействия в операционной системе Windows

Механизм DDE (Dynamic Data Exchange) представляет собой механизм динамического обмена данными, позволяющий создать постоянно действующие каналы между несколькими одновременно работающими приложениями операционной системы Windows. Эти каналы могут создаваться автоматически при запуске приложения или при необходимости, а также по явному запросу пользователя. После создания каналы могут функционировать без вмешательства пользователя. Механизм DDE основан на использовании стандартной архитектуры "клиент - сервер". В терминологии DDE приложение, посылающее данные называется сервером, а принимающее - клиентом.
В DDE определены несколько стандартных типов сообщений, при помощи которых можно передавать в приложения дескрипторы объектов глобальной памяти, содержащих необходимые данные.
Для обработки сообщений, называемых в DDE транзакциями, используется привычный для Windows способ: для приложения, использующего DDE назначается функция обратного вызова.
Для работы с использованием технологии DDE приложение-клиент и приложение сервер должны зарегистрироваться в динамической библиотеке DDEML. Кроме этого сервер должен зарегистрировать предоставляемые им сервисы, а также темы и элементы данных, входящие в эти сервисы. После этого клиент может создавать канал, ассоциированный с сервисом и темой, поддерживаемыми сервером.
По каналу могут передаваться данные трех типов: Запрос клиента к серверу на передачу обратно определенных данных, Передача данных от клиента к серверу, Передача клиентом серверу команды, которую сервер должен выполнить. В более поздних версиях операционных систем семейства Windows механизм DDE был дополнен управляющей библиотекой динамического обмена DDEML, которая позволяет упростить использование механизма DDE, а также является совместимой с операционными системами Windows NT и Windows 95, не поддерживающими старый стандарт, и с сетевым вариантом DDE - Network DDE.

Архитектура системы

Архитектура разработанной системы представляет собой механизм взаимодействия клиент-сервер, причем этот механизм реализуется на нескольких уровнях.
На глобальном уровне конечным клиентом является удаленный пользователь, получающий доступ к системе посредством сети Internet, а конечным сервером является сервер СУБД Oracle. Далее эту схему можно детализировать и разбить на следующие взаимодействия по схеме клиент-сервер:
Взаимодействия удаленный пользователь - WWW сервер Alibaba; Взаимодействие обработчик, связанный с HTML документом - серверное приложение; Серверное приложение - сервер СУБД. Шлюз к базе данных состоит из двух частей: резидентной (серверной) и вызываемой WWW сервером (клиентской).
Клиентская часть, указанная в HTML документе, передаваемом удаленному пользователю, запускается при помощи вызова WinExec() WWW сервером Alibaba. Ей передаются данные, введенные пользователем посредством диалогов в HTML документ, которые клиентское приложение передает серверному. После выполнения серверным приложением SQL запроса, клиентское приложение получает результаты от серверного приложения, производит их декодирование и формирует на их основе HTML документ, направляемый WWW серверу для последующей передачи его удаленному клиенту.
Серверная часть, называемая серверным приложением, устанавливает соединение с базой данных, принимает данные, заданные пользователем в запросе, от клиентского приложения-обработчика, формирует запрос к базе данных на языке SQL на основе данных, полученных от клиентского приложения, исполняет этот запрос и передает результаты клиентскому приложению.
Хотя клиентских приложений может быть много, в каждый момент времени существует единственное соединение (connection) с базой данных. Несмотря на то, что СУБД может одновременно поддерживать несколько соединений, используемая схема позволяет работать с БД во-первых, большему числу пользователей, во-вторых, уменьшает время обработки запроса, и, в- третьих, экономит оперативную память, включая, в общем-то одинаковую для всех клиентских приложений процедуру формирования и посылки SQL-запроса, в единое серверное приложение.

Интерфейс общения с пользователем посредством Internet

Основными функциями интерфейса для работы с удаленным пользователем являются построение пользователем запроса на поиск информации о требуемой литературе в базе данных и преобразование результатов поиска к удобному для восприятия пользователем представлению.
Реализация интерфейса пользователя проводится на стандартизированном языке WWW серверов HTML версии 2.0. Данный язык позволяет организовывать гипертекстовые и гипермедиа документы , в узлах которых могут находиться документы одного из стандартных MIME типов. Второй уровень HTML позволяет встраивать в документы, передаваемые пользователю , стандартные объекты диалога. Данные, введенные пользователем, посредством CGI интерфейса передаются приложению-обработчику. При построении интерфейса конструирования запросов к базе данных было принято предположение о том, что пользователь может для запроса использовать логическое выражение любой конструкции.
При построении указанного выражения из атомов допускается использование логических операций NOT, AND, OR и скобок для задания порядка вычисления выражений. Данный подход является серьезным обобщением стандартного конструирования логических выражений, используемого в большинстве программных средств. Атомы представляются следующим образом: .
На основе проведенного статистического анализа запросов в библиотеках и консультаций со специалистами в области библиотечного дела были выделены следующие критерии поиска:
автор, коллективный автор, тематический рубрикатор, название фрагмент названия год издания, ISSN. При отсутствии выражения для соответствующего критерия считается , что данный критерий следует не учитывать в этой части запроса. После формирования указанной части выражения пользователю предоставляется возможность либо сразу выполнить запрос, либо продолжить его конструирование. При продолжении конструирования предыдущая часть запроса предоставляется пользователю в качестве восьмого атома для конструирования (наряду с теми же семью стандартными критериями). Пользователь может уточнять запрос как за счет использования семи стандартных критериев поиска, так и за счет модификации предыдущей части запроса путем добавления в нее новых атомов, модификации и удаления старых. Данный процесс продолжается итеративно до получения пользователем требуемого запроса, которые пользователь и отсылает для исполнения.
Для перехода от одного бланка к следующему в процессе уточнения запроса согласно стандарту CGI используются приложения-обработчики, которые и генерируют новые формы для ввода данных с учетом ранее введенных пользователем данных.
Получаемые из базы данных результаты запроса приложения формируют в цепочку HTML документов MIME типа "text/html" и передают их пользователю посредством WWW сервера.

Передача данных от пользователя к обработчику

Передача данных от удаленного пользователя системы к программе обработчику идет через сеть Internet на основе интерфейса Windows CGI. Все данные введенные пользователем вначале передаются WWW серверу, который преобразует их к формату, отвечающему требованиям стандарта CGI, и передает их программе обработчику, названному выше клиентским приложением, Данные от удаленного клиента к WWW серверу поступают на основе протокола HTTP (Hypertext Transfer Protoсol).
Данные передаваемые WWW сервером обработчику можно разделить на две группы, исходя из источника их получения:
Информация о клиенте, Она включает в себя такие данные как URL адрес удаленного клиента, его средство навигации по Internet, операционную систему, метод доступа, используемый клиентом, регистрационные данные пользователя и прочую подобную информацию. Данные такого рода используются обработчиком для настройки на конкретного клиента. Информация введенная пользователем в HTML документ. Для осуществления ввода данных в HTML документы, для их последующей передачи WWW серверу используется язык HTML второго уровня, который допускает размещение в документе стандартных объектов диалога. Для этого в HTML второго уровня используется тэг FORM, внутри которого и размещаются тэги, соответствующие объектам диалога. Для передачи введенных данных HTML предусматривает использование одного из двух основных методов передачи: GET и POST. Взаимодействие с использованием метода GET происходит гораздо быстрее, но этот метод в соответствии со стандартом CGI рекомендуется использовать только, если в результате обработки данных не произойдет никаких изменений в окружающем мире. В соответствии со стандартом CGI при использовании метода GET данные введенные пользователем, помещаются в переменную окружения QUERY_STRING в виде поле1=значение1 & поле2=значение2... с заменой пробелов на символ '+', а специальных символов на их коды. При использовании метода POST преобразованные, как и при использовании метода POST, данные поступают в стандартный поток ввода обработчика. Стандарт Windows CGI при использовании обоих методов помещает значение переменной QUERY_STRING в раздел [CGI] файла данных, а при использовании метода POST WWW сервер еще и декодирует строку - значение этой переменной и помещает пары поле-значение в раздел [Form Literal файла данных, а при необходимости, также и в разделы [Form External] и [Form Huge].

Взаимодействие серверного и клиентского приложений

Задачами серверного приложения являются: получение от клиентского приложения текста SQL запроса, исполнение указанного SQL запроса, передача полученных данных из результирующего множества клиентскому приложению по его запросам, контроль и обработка возникающих ошибок. Для решения этих задач и поддержания архитектуры клиент-сервер в разработанной системе применена следующая схема взаимодействия клиентского и серверного приложений: Серверное приложение при начале своей работы инициализирует переменные окружения и создает соединение с ODBC драйвером. Запускаемое WWW сервером клиентское приложение регистрирует сервис в библиотеке DDEML и посылает запрос на создание канала с сервером. Серверное приложение в ответ на запрос о создании канала проверяет наличие свободной строки в таблице регистрации клиента. В случае наличия свободной строки серверное разрешает создание канала и помечает строку в таблице регистрации как занятую, указывая в графе статуса клиентского приложения признак создания канала. Клиентское посылает серверному приложению готовый текст SQL запроса, подготовленного на основе данных, введенных удаленным пользователем. Серверное приложение при появлении транзакции передачи данных клиентом записывает в любую строку со статусом клиентского приложения "создан канал" в таблице регистрации клиентских приложений идентификатор используемого для передачи данных канала и сам получаемых текст SQL запроса. Статус клиентского приложения изменяется на "передан текст SQL запроса". Клиентское приложение, получив транзакцию об окончании передачи данных серверному приложению, посылает серверному приложению запрос на асинхронную передачу данных клиентскому приложению. Серверное приложение, получив запрос клиентского приложение, производит поиск в таблице регистрации идентификатора канала, использованного клиентским приложением для пересылки запроса. Найдя нужную строку серверное приложение меняет статус клиентского приложения в этой строке на "первая группа данных получена", извлекает ранее переданный этим клиентским приложением текст SQL запроса, подготавливает SQL запрос и исполняет его. Идентификатор подготовленного запроса серверное приложение записывает в таблицу регистрации в соответствующую клиентскому приложению строку. После получение первых результатов SQL запроса серверное приложение сравнивает количество строк в результирующем множестве с оговоренным максимальным количеством одновременно передаваемых клиентскому приложению записей и формирует один из следующих признаков: записей в результирующем множестве не более максимального передаваемого числа; записей в результирующем множестве больше максимального передаваемого числа; записи, удовлетворяющие переданным в запросе критериям, отсутствуют; в процессе получения данных возникла ошибка. Сформированный признак вместе с полученными данными передается клиентскому приложению. Если не был сформирован признак о наличии дополнительных данных, то строка таблицы регистрации занимаемая клиентским приложением освобождается и в графу статуса помещается признак "свободна". Клиентское приложение, получив транзакцию об окончании асинхронного запроса к серверному приложению, анализирует переданный серверным приложением признак. Если, согласно признаку, получены еще не все данные, то клиентское приложение посылает повторный запрос на передачу данных серверному приложению. Серверное приложение, получив транзакцию, производит идентификацию клиентского приложения по идентификатору канала. Если, согласно статусу клиентского приложения, оно ожидает дополнительные данные, то серверное приложение извлекает из таблицы регистрации идентификатор SQL запроса и продолжает получение результатов этого, ранее выполненного запроса. Далее взаимодействие серверного и клиентского приложений происходит как и в пункте 4. Пункт 5 повторяется до момента передачи всего полученного результирующего множества от серверного к клиентскому приложению. По завершению этой передачи строка таблицы регистрации занимаемая клиентским приложением освобождается и в графу статуса помещается признак "свободна". Клиентское приложение закрывает канал и деинициализирует себя в библиотеке DDEML.

Переработка результатов SQL запроса и передача их пользователю

Данные получаемые клиентским приложением от серверного приложения подвергаются дальнейшей обработке. Так как удаленный клиент системы использует одно из средств навигации по Internet, и согласно стандарту Windows CGI, WWW серверу должен быть передан документ одного из MIME типов. Исходя из того, что передаваемые данные представляют собой строки символов , и необходимости разбиения результатов для удобства их анализа на несколько файлов, для возвращаемых документов был выбран MIME тип "text/html".
Клиентское приложение получает данные от серверного приложения в виде записей, разделенных символом STRUCTDELIMITER. Поля записи разделены символом FIELDDELIMITER. Клиентское приложение получает из файла данных CGI имя и путь доступа к файлу, который должен быть передан WWW серверу, создает этот файл и записывает в него строку, идентифицирующую MIME тип документа: Content-type text/html. Далее полученную первую порцию данных от серверного приложения клиентское приложение после декодировки записей и полей записывает в созданный файл. Клиентское приложение, анализируя полученный от серверного приложения признак, получает информацию о наличии дополнительной группы данных, Если серверное приложение готово передать следующую часть данных, то клиентское приложение создает временный файл и помещает в первый файл после данных ссылку на созданный файл, то есть указывая его URL. Затем клиентское приложение получает от серверного приложения и записывает в файл следующую порцию данных. Эти операции, включая создание очередных файлов, повторяются пока серверное приложение передает результирующее множество клиентскому приложению. В результате этого создается цепочка HTML файлов, которые удаленный пользователь может последовательно просматривать с помощью своего средства навигации по Internet ( Netscape, Microsoft Internet Explorer и т.д.), Просмотр цепочки документов в прямом направлении обеспечивается наличием встроенных в документы ссылок на следующий документ, а просмотр в обратном направлении поддерживается встроенной в навигаторы возможностью отката к предыдущему документу.

Описание общей схемы функционирования системы

Общая схема функционирования созданной системой может быть структурно отображена нижеприведенной диаграммой.
Функционально созданное клиентское приложение разбивается на следующие блоки : Блок инициализации клиентского приложения и установки соединения с серверным приложением. Блок обработки заданных удаленным клиентом данных и создания текста запроса на языке SQL. Блок, преобразующий данные из результирующего множества, полученные от серверного приложения, к цепочке HTML документов, которые будут переданы удаленному пользователю. Блок, отвечающий за деинициализацию клиентского приложения, реакцию на возникающие исключительные ситуации и прочие организационные действия. Блок, отвечающий за получение данных, введенных удаленным клиентом в HTML документ. Блок, организующий пересылку серверному приложению текста составленного SQL запроса и получение записей из результирующего множества. В свою очередь, серверное приложения, исходя из набора решаемых задач, функционально разбивается на следующие блоки: Блок, отвечающий за подготовку SQL запроса, исполнение, а также за получение данных из результирующего множества. Блок, организующий получение от клиентского приложения текста SQL запроса и за пересылку результатов его исполнения обратно клиентскому приложению. Блок, инициализирующий серверное приложение, регистрирующий сервис в библиотеке DDEML и устанавливающий соединение с ODBC драйвером. Блок деинициализации серверного приложения, обработки исключительных ситуаций и выполнения прочих служебных функций.

Заключение

В ходе решения поставленной задачи - реализации информационно-поисковой системы библиотечного типа - был проделан следующий объем работ:
Во-первых, выбраны методы и механизмы, наиболее точно отвечающие требованиям к системе, на основе которых разрабатывалась система.
Во-вторых, была разработана схема функционирования системы и на основе ее анализа реализовано архитектурное решение системы.
В третьих, была проведена реализация системы с использование языков C, HTML и SQL.
В четвертых, проведено тестирование и отладка системы с моделированием взаимодействия нескольких клиентов с системой.
По результатам проведенных тестов разработанная система показала свою способность с достаточной степенью надежности выполнять поставленную перед ней задачу.



  • Главная
  • Новости
  • Новинки
  • Скрипты
  • Форум
  • Ссылки
  • О сайте




  • Emanual.ru – это сайт, посвящённый всем значимым событиям в IT-индустрии: новейшие разработки, уникальные методы и горячие новости! Тонны информации, полезной как для обычных пользователей, так и для самых продвинутых программистов! Интересные обсуждения на актуальные темы и огромная аудитория, которая может быть интересна широкому кругу рекламодателей. У нас вы узнаете всё о компьютерах, базах данных, операционных системах, сетях, инфраструктурах, связях и программированию на популярных языках!
     Copyright © 2001-2024
    Реклама на сайте