Сайт о телевидении

Сайт о телевидении

» » Построение клиент серверного приложения. Клиент-серверное приложение

Построение клиент серверного приложения. Клиент-серверное приложение

В этом примере мы разработаем простой сервер и простую клиентскую программу, ведущих между собой "неспешный" диалог. Клиента построим по технике Windows Forms , а сервер - Windows Service . Сервер будет иметь набор готовых маркированных ответов, ждать маркированных запросов клиентов и отвечать им соответствующими сообщениями. Это настроит нас на создание еще более сложной системы - просмотру дистанционных рисунков из БД, которой мы займемся позже.

Создание клиента

Начнем с клиентской программы, которая может запускаться во многих экземплярах ("http://msdn.microsoft.com/ru-ru/library/system.net.sockets.tcplistener.accepttcpclient.aspx ")


Таблица 19.7.
Элемент Свойство Значение
Form Text Client
Size 300; 300
ListBox (Name) listBox
Dock Top
Font Arial; 12pt
Items
  1. Привет!
  2. Лелик
  3. Как жизнь
  4. Оттопыремся сегодня?
  5. Ну тогда пока!
SelectionMode One
Size 292; 119
Button (Name) btnSubmit
AutoSize True
Font Arial; 10pt
Location 96; 127
Size 101; 29
Text Отправить
TextBox (Name) textBox
Dock Bottom
Location 0; 162
Multiline True
ScrollBars Vertical
Size 292; 105

Остальные нужные настройки элементов формы добавим программно.

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; // Дополнительные пространства имен using System.IO; using System.Net; using System.Net.Sockets; using System.Threading; namespace SimpleClient { public partial class Form1: Form { int port = 12000; String hostName = "127.0.0.1";// local TcpClient client = null;// Ссылка на клиента public Form1() { InitializeComponent(); // Выделить первый элемент списка listBox.SelectedIndex = 0; listBox.Focus(); // Контекстное меню для очистки TextBox ContextMenuStrip contextMenu = new ContextMenuStrip(); textBox.ContextMenuStrip = contextMenu; ToolStripMenuItem item = new ToolStripMenuItem("Очистить"); contextMenu.Items.Add(item); item.MouseDown += new MouseEventHandler(item_MouseDown); } // Отослать запрос и получить ответ private void btnSubmit_Click(object sender, EventArgs e) { if (listBox.SelectedIndices.Count == 0) { MessageBox.Show("Выделите сообщение"); return; } try { // Создаем клиента, соединенного с сервером client = new TcpClient(hostName, port); // Сами задаем размеры буферов обмена (Необязательно!) client.SendBufferSize = client.ReceiveBufferSize = 1024; } catch { MessageBox.Show("Сервер не готов!"); return; } // Записываем запрос в протокол AddString("Клиент: " + listBox.SelectedItem.ToString()); // Создаем потоки NetworkStream, соединенные с сервером NetworkStream streamIn = client.GetStream(); NetworkStream streamOut = client.GetStream(); StreamReader readerStream = new StreamReader(streamIn); StreamWriter writerStream = new StreamWriter(streamOut); // Отсылаем запрос серверу writerStream.WriteLine(listBox.SelectedItem.ToString()); writerStream.Flush(); // Читаем ответ String receiverData = readerStream.ReadLine(); // Записываем ответ в протокол AddString("Сервер: " + receiverData); // Закрываем соединение и потоки, порядок неважен client.Close(); writerStream.Close(); readerStream.Close(); } // Добавление строки, когда TextBox включен в режиме Multiline private void AddString(String line) { StringBuilder sb = new StringBuilder(textBox.Text); StringWriter sw = new StringWriter(sb); sw.WriteLine(line); textBox.Text = sw.ToString(); } // Очистка списка через контекстное меню void item_MouseDown(object sender, MouseEventArgs e) { textBox.Clear(); listBox.Focus(); } } }

Получив соединение с сервером, мы создаем два потока NetworkStream и упаковываем их в оболочки, удобные для управления чтением/записью. Обмен с сервером отображаем в протоколе TextBox . Для очистки протокола динамически создали контекстное меню.

Класс TcpClient , который мы использовали в коде, является высокоуровневой (и упрощенной) оболочкой сокета (класса Socket ). Если потребуется более низкоуровневое управление сокетом (более детальное), то ссылка на него хранится в свойстве TcpClient.Client . Но поскольку это свойство защищенное (protected ), то доступ к нему возможен только из производного от TcpClient класса.

Если сейчас запустить приложение SimpleClient , то оно будет работать, но при попытке что-то отослать на сервер, будет выдаваться сообщение, что сервер не готов. Сервера-то еще пока вообще нет, создадим его.

Создание сервера

Серверную программу сделаем резидентной по шаблону Windows Service , как мы это делали в предыдущем примере, хотя можно сделать и с интерфейсом, главное, чтобы он был запущен в единственном экземпляре на локальном компьютере. Если программа-сервер включена в глобальную сеть, то с используемым IP и портом она должна быть единственной в этой сети. Поэтому на использование сетевого IP для глобальной сети нужно получать разрешение.



using System; using System.ComponentModel; using System.Configuration.Install; using System.ServiceProcess; namespace SimpleServer { // Во время установки сборки следует вызвать установщик public partial class Installer1: Installer { private ServiceInstaller serviceInstaller; private ServiceProcessInstaller serviceProcessInstaller; public Installer1() { // Создаем настройки для Службы serviceInstaller = new ServiceInstaller(); serviceProcessInstaller = new ServiceProcessInstaller(); // Имя Службы для машины и пользователя serviceInstaller.ServiceName = "SimpleServerServiceName"; serviceInstaller.DisplayName = "SimpleServer"; serviceInstaller.StartType = ServiceStartMode.Manual;// Запуск вручную // Как будет запускаться Служба this.serviceProcessInstaller.Account = ServiceAccount.LocalService; this.serviceProcessInstaller.Password = null; this.serviceProcessInstaller.Username = null; // Добавляем настройки в коллекцию текущего объекта this.Installers.AddRange(new Installer { serviceInstaller, serviceProcessInstaller }); } } }

using System; using System.Collections.Generic; using System.Text; // Дополнительные пространства имен using System.IO; using System.Net; using System.Net.Sockets; using System.Threading; using System.ServiceProcess; using System.Collections; namespace SimpleServer { class Service1: ServiceBase { TcpListener server = null;// Ссылка на сервер int port = 12000; String hostName = "127.0.0.1";// local IPAddress localAddr; String answers = { "1. Ты кто?", "2. Привет, Лелик!", "3. Лучше всех!", "4. Конечно, на полную катушку", "5. До вечера!" }; // Конструктор public Service1() { localAddr = IPAddress.Parse(hostName);// Конвертируем в другой формат Thread thread = new Thread(ExecuteLoop); thread.IsBackground = true; thread.Start(); } private void ExecuteLoop() { try { server = new TcpListener(localAddr, port);// Создаем сервер-слушатель server.Start();// Запускаем сервер String data; // Бесконечный цикл прослушивания клиентов while (true) { if (!server.Pending())// Очередь запросов пуста continue; TcpClient client = server.AcceptTcpClient();// Текущий клиент // Сами задаем размеры буферов обмена (Необязательно!) // По умолчанию оба буфера установлены размером по 8192 байта client.SendBufferSize = client.ReceiveBufferSize = 1024; // Подключаем NetworkStream и погружаем для удобства в оболочки NetworkStream streamIn = client.GetStream(); NetworkStream streamOut = client.GetStream(); StreamReader readerStream = new StreamReader(streamIn); StreamWriter writerStream = new StreamWriter(streamOut); // Читаем запрос data = readerStream.ReadLine(); // Отправляем ответ int index; if (int.TryParse(data.Substring(0, data.IndexOf(".")), out index)) data = answers; else data = data.ToUpper(); writerStream.WriteLine(data); writerStream.Flush(); // Закрываем соединение и потоки, порядок неважен client.Close(); readerStream.Close(); writerStream.Close(); } } catch (SocketException) { } finally { // Останавливаем сервер server.Stop(); } } } }

Чтобы передать данные и получить ответ, клиентское приложение создает двунаправленный сокет (или два однонаправленных), в котором указывает адрес соединения с сокетом другого, серверного, приложения. Если соединение установлено (сервер работает), то клиентское приложение подключает к сокету сетевой поток NetworkStream и через него выполняет передачу и прием данных.

На другой стороне соединения сервер TcpListener в бесконечном цикле прослушивает очередь соединений с клиентами. Если какой-то клиент с ним соединился (server.Pending()!=false ), то сервер извлекает этого клиента методом AcceptTcpClient() - создает сокет для приема/передачи с готовым обратным адресом, создает двунаправленный поток (или два однонаправленных), затем читает запрос и передает ответ.



Обратите внимание, что если код работы нашей серверной программы не упаковать в отдельную нить Thread (поток выполнения), то в окне служб эта программа операционной системой запускаться не будет (попробуйте!). Причина в том, что в коде метода ExecuteLoop() в сервере используется бесконечный цикл прослушивания очереди запросов клиентов. Если этот цикл оставить в основном потоке выполнения (Thread ) приложения, то оно просто зациклится и не сможет само нормально завершиться. Поэтому код с циклом мы помещаем в отдельный поток (трэд) и делаем его фоновым, чтобы он закрывался вместе с основным потоком приложения (трэдом сервера).

Важное замечание

Поток NetworkStream является двухсторонним фиксированной длины. Методом GetStream() он только устанавливает адресное соединение между сокетами клиента и сервера. Но реальная его длина определяется сообщением отправляющей стороны. Можно для приема/передачи использовать один поток, но тогда длина сообщения, отправляемого сервером, не должна превышать длину сообщения, принятого им от клиента (чуть глаза не отсидел!). Поэтому мы и используем на каждой стороне два потока для раздельной однонаправленной передачи между двумя узлами сетевого соединения.

Пример 3. Клиент-серверное приложение просмотра рисунков из БД

На предыдущем простом примере мы познакомились (чуть-чуть) с пронципами создания сетевых приложений. А теперь построим более сложный пример, когда клиент запрашивает рисунки, а сервер извлекает их из хранилища и посылает клиенту. В Упражнении 7 нами было разработано три разных хранилища рисунков и три программы просмотра. В данном примере воспользуемся БД Pictures.my2.mdb с готовыми рисунками и на ее основе создадим сетевое приложение (для тех, кто не делал Упражнение 7 , БД прилагается в каталоге Source/Data ).

Построение клиента

Для клиента построим оконное приложение типа WPF с пользовательским интерфейсом, частично заимствованным из Примера 6 Упражнения 7 .


Сервер не готов, ждите! Мы пытаемся связаться, извините за неудобства...

Для вывода заставки с текстом о неготовности сервера мы применили элемент Viewbox , в который поместили еще один элемент Border с текстовым содержимым. Такой "огород" позволит увеличивать заставку пропорционально размеру окна. Однако введение элемента Viewbox начинает заметно притормаживать перерисовку интерфейса при перемещениях окна, потому что он пытается постоянно пересчитывать масштабы своих дочерних элементов. Имена мы присвоили только тем интерфейсным элементам, которыми собираемся управлять в процедурном коде.

using System; using System.Collections.Generic; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Media.Imaging; using System.Windows.Shapes; // Дополнительные пространства имен для Stream using System.IO; using IO = System.IO; // Псевдоним для адресации Path using System.Windows.Threading; // Для DispatcherTimer // Дополнительные пространства имен для Socket //using System.Net; using System.Net.Sockets; using System.Collections; // List namespace PicturesClientDB { public partial class Window1: Window { int port = 12000; String hostName = "127.0.0.1"; // local TcpClient client = null; // Ссылка на клиента String sendMessage = "!!!GetNames!!!"; // Запрос на список (позаковыристей) Char separator = { "#" }; // Для преобразования ответа в массив имен DispatcherTimer timer; // Таймер // Конструктор public Window1() { InitializeComponent(); // Создаем и запускаем таймер timer = new DispatcherTimer(); timer.Tick += new EventHandler(timer_Tick); timer.Interval = TimeSpan.FromSeconds(1); timer.Start(); } // Инициирует обращение к серверу void timer_Tick(object sender, EventArgs e) { Execute(listBox); } private void listBox_SelectionChanged(object sender, SelectionChangedEventArgs e) { Execute((ListBox)sender); } void Execute(ListBox lst) { // Заполняем список именами рисунков try { // Если сервер доступен, создаем клиента client = new TcpClient(hostName, port); } catch { // Сервер не готов, запускаем таймер и выходим if (Prompt.Visibility != Visibility.Visible) { Prompt.Visibility = Visibility.Visible; timer.Start(); } return; } switch (sendMessage) { case "!!!GetNames!!!": // Получаем и привязываем имена рисунков к списку lst.ItemsSource = GetNames(); // Выделяем первый элемент списка, чтобы вызвать SelectionChanged lst.SelectedIndex = 0; lst.Focus(); sendMessage = ""; break; default: // Скрываем сообщение и останавливаем таймер if (Prompt.Visibility == Visibility.Visible) { Prompt.Visibility = Visibility.Hidden; timer.Stop(); } // Получаем рисунок и отображаем пользователю кистью String name = lst.SelectedValue.ToString(); BitmapImage bi = new BitmapImage(); bi.BeginInit(); // Получаем от сервера рисунок и обертываем его в поток памяти bi.StreamSource = new MemoryStream(GetPicture(name)); bi.EndInit(); Pictures.picture.ImageSource = bi;// Передаем рисунок фону Border break; } } private String GetNames() { String names; // Создаем потоки сетевых соединений StreamReader readerStream = new StreamReader(client.GetStream()); StreamWriter writerStream = new StreamWriter(client.GetStream()); // Отсылаем запрос серверу writerStream.WriteLine(sendMessage); writerStream.Flush(); // Читаем ответ String receiverData = readerStream.ReadLine(); names = receiverData.Split(separator);// Преобразуем в строковый массив // Закрываем соединение и потоки, порядок неважен client.Close(); writerStream.Close(); readerStream.Close(); return names; } Byte GetPicture(String name) { // Создаем потоки сетевых соединений NetworkStream readerStream = client.GetStream(); StreamWriter writerStream = new StreamWriter(client.GetStream()); // Отсылаем запрос серверу writerStream.WriteLine(name); writerStream.Flush(); // Читаем ответ // ReceiveBufferSize - размер буфера для входящих данных // SendBufferSize - размер буфера для исходящих данных List list = new List(client.ReceiveBufferSize);// С приращением capacity Byte bytes = new Byte; // Размер буфера сокета int count = 0; // Порции входящих данных while ((count = readerStream.Read(bytes, 0, bytes.Length)) != 0) for (int i = 0; i < count; i++) list.Add(bytes[i]); // Преобразуем в массив результата bytes = new Byte; list.CopyTo(bytes); // Закрываем соединение и потоки, порядок неважен client.Close(); writerStream.Close(); readerStream.Close(); return bytes; } } // Для привязки к ресурсу class Pictures { // Поле public static ImageBrush picture = new ImageBrush(); static Pictures() { // Дежурный рисунок заставки picture.ImageSource = new BitmapImage(new Uri(@"flower2.jpg", UriKind.Relative)); picture.Stretch = Stretch.Fill; picture.Opacity = 1.0D; } // Привязываемое в интерфейсе свойство public static ImageBrush Picture { get { return picture; } } } }

Обратите внимание, что при отображении рисунков мы отказались от традиционного элемента Image , как это делали в предыдущем упражнении. А для разнообразия поступили совершенно нетрадиционно (по турецки). Теперь мы рисунки будем отображать кистью ImageBrush в фоне прямоугольника Border через привязанный к нему объект Pictures . Конечно, в жизни так извращаться вряд ли придется, но и такой вариант где-нибудь может пригодиться.


Заставка появится сразу же, как будет обнаружен факт отсутствия или остановки сервера. А после обнаружения сервера заставка исчезнет. Этот механизм немедленно сработает благодаря используемому нами системному таймеру . Однако, сервера пока еще совсем нет и следует его изготовить.

Построение сервера БД как службу
  • Командой File/Add/New Project добавьте к решению NetworkStream новый проект с именем PicturesServerDB типа Windows Service


using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Diagnostics; using System.ServiceProcess; using System.Text; // Дополнительные пространства имен для ADO.NET using System.Data.OleDb; using System.Data.Common; // Дополнительные пространства имен using System.IO; using System.Net; using System.Net.Sockets; using System.Threading; using System.Collections; namespace PicturesServerDB { public partial class Service1: ServiceBase { int port = 12000; String hostName = "127.0.0.1"; // local IPAddress localAddr; TcpListener server = null; // Ссылка на сервер String separator = "#"; // Разделитель имен в строке ответа String connectionString; // Строка соединения с БД public Service1() { // Извлекаем в поле строку соединения с БД из файла App.config connectionString = System.Configuration.ConfigurationManager. ConnectionStrings["PicturesDB"].ConnectionString; // Конвертируем IP в другой формат localAddr = IPAddress.Parse(hostName); // Запускаем в новом потоке (ните) Thread thread = new Thread(ExecuteLoop); thread.IsBackground = true; thread.Start(); } private void ExecuteLoop() { try { server = new TcpListener(localAddr, port);// Создаем сервер-слушатель server.Start();// Запускаем сервер // Бесконечный цикл прослушивания клиентов while (true) { // Проверяем очередь соединений if (!server.Pending())// Очередь запросов пуста continue; TcpClient client = server.AcceptTcpClient();// Текущий клиент // Создаем потоки сетевых соединений StreamReader readerStream = new StreamReader(client.GetStream()); NetworkStream streamOut = client.GetStream(); StreamWriter writerStream = new StreamWriter(streamOut); // Читаем команду клиента String receiverData = readerStream.ReadLine(); // Распознаем и исполняем switch (receiverData) { case "!!!GetNames!!!":// Посылаем имена, разделенные сепаратором String names = GetNames(); writerStream.WriteLine(names); // Используем через оболочку writerStream.Flush(); break; default:// Посылаем рисунок Byte bytes = GetPicture(receiverData); streamOut.Write(bytes, 0, bytes.Length);// Используем напрямую streamOut.Flush(); break; } // Закрываем соединение и потоки, порядок неважен client.Close(); readerStream.Close(); writerStream.Close(); } } finally { // Останавливаем сервер server.Stop(); } } // Извлечение из БД имен рисунков и упаковка их в одну строку для пересылки клиенту string GetNames() { // Создаем и настраиваем инфраструктуру ADO.NET OleDbConnection conn = new OleDbConnection(connectionString); OleDbCommand cmd = new OleDbCommand("SELECT FileName FROM MyTable"); cmd.Connection = conn; conn.Open(); // Извлекаем имена рисунков OleDbDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection); // Формируем строку исходящих данных StringBuilder sb = new StringBuilder(); foreach (DbDataRecord record in reader)// Равносильно чтению reader.Read() sb.Append(((string)record["FileName"]).Trim() + separator); // Соединение здесь закроет сам объект DataReader после прочтения всех данных // в соответствии с соглашением при его создании CommandBehavior.CloseConnection // Удаляем лишний последний символ сепаратора sb.Replace(separator, String.Empty, sb.ToString(). LastIndexOf(separator), separator.Length); return sb.ToString(); } // Извлечение из БД самого рисунка для отправки клиенту byte GetPicture(String name) { // Создаем и настраиваем инфраструктуру ADO.NET OleDbConnection conn = new OleDbConnection(); conn.ConnectionString = connectionString; // Создаем и настраиваем объект команды, параметризованной по имени рисунка OleDbCommand cmd = new OleDbCommand(); cmd.Connection = conn; cmd.CommandType = CommandType.Text; // Необязательно! Установлено по умолчанию cmd.CommandText = "SELECT Picture FROM MyTable WHERE FileName=?"; cmd.Parameters.Add(new OleDbParameter()); cmd.Parameters.Value = name;// Имя рисунка OleDbDataAdapter adapter = new OleDbDataAdapter(cmd); // Извлекаем рисунок из БД DataTable table = new DataTable(); adapter.Fill(table); byte bytes = (byte)table.Rows["Picture"]; // Подключаемся к рисунку return bytes; } } }

Технология клиент-сервер предусматривает наличие двух самостоятельных взаимодействующих процессов - сервера и клиента, связь между которыми осуществляется по сети.

Серверами называются процессы, отвечающие за поддержку и файловой системы, а клиентами - процессы, которые посылают запрос и ожидают ответ от сервера.

Модель клиент-сервер используется при построении системы на основе СУБД, а также почтовые системы. Существует еще так называемая файл-серверная архитектура, которая существенно отличается от клиент-серверной.

Данные в файл-серверной системе сохраняются на файловом сервере (Novell NetWare или WindowsNT Server), а обрабатываются они на рабочих станциях посредством функционирования "настольных СУБД", таких как Access, Paradox, FoxPro и т.п.

СУБД располагается на рабочей станции, а манипулирование данными производится несколькими независимыми и несогласованными между собой процессами. Все данные при этом передаются с сервера по сети на рабочую станцию, что замедляет скорость обработки информации.

Технология клиент-сервер реализована функционированием двух (как минимум) приложений - клиентов и сервера, которые делят функции между собой. За хранение и непосредственное манипулирование данных отвечает сервер, примером которого может быть SQLServer, Oracle, Sybase и другие.

Пользовательский интерфейс формирует клиент, в основе построения которого используются специальные инструменты или настольные СУБД. Логическая обработка данных выполняется частично на клиенте, и частично на сервере. Посылка запросов на сервер выполняется клиентом, обычно на языке SQL. Полученные запросы обрабатываются сервером, и клиенту (клиентам) возвращается результат.

При этом данные обрабатываются там же, где они хранятся - на сервере, поэтому большой объем их не передается по сети.

Преимущества архитектуры клиент-сервер

Технология клиент-сервер привносит в информационную систему такие качества:

  • Надежность

Модификация данных осуществляется сервером баз данных при помощи механизма транзакций, придающего совокупности операций такие свойства, как: 1) атомарность, которая обеспечивает целостность данных при любом завершении транзакции; 2) независимость транзакций разных пользователей; 3) устойчивость к сбоям - сохранение результатов завершения транзакции.

  • Масштабируемость, т.е. способность системы не зависеть от количества пользователей и объемов информации без замены используемого программного обеспечения.

Технология клиент-сервер поддерживает тысячи пользователей и гигабайты информации при соответствующей аппаратной платформе.

  • Безопасность, т.е. надежная защита информации от
  • Гибкость. В приложениях, работающих с данными, выделяют логических слои: пользовательский интерфейс; правила логической обработки; управление данными.

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

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

Трехуровневое приложение допускает промежуточный уровень, который реализует бизнес-правила, являющиеся наиболее изменяемыми компонентами.

Несколько уровней позволяют гибко и с наименьшими затратами адаптировать имеющееся приложение к постоянно модифицируемым требованиям бизнеса.

Client-server ) - сетевая архитектура, в которой устройства являются либо клиентами , либо серверами . Клиентом (front end) является запрашивающая машина (обычно ПК), сервером (back end) - машина, которая отвечает на запрос. Оба термина (клиент и сервер) могут применяться как к физическим устройствам, так и к программному обеспечению.

Сеть с выделенным сервером (англ. Сlient/Server network ) - это локальная вычислительная сеть (LAN) , в которой сетевые устройства централизованы и управляются одним или несколькими серверами. Индивидуальные рабочие станции или клиенты (такие, как ПК) должны обращаться к ресурсам сети через сервер(ы).


Wikimedia Foundation . 2010 .

Смотреть что такое "Клиент-серверное приложение" в других словарях:

    Может значить: Прикладная компьютерная программа см. Прикладное программное обеспечение. Веб приложение клиент серверное приложение, в котором клиентом выступает браузер, а сервером веб сервер. Приложение (лингвистика) … … Википедия

    Веб приложение клиент серверное приложение, в котором клиентом выступает браузер, а сервером веб сервер. Логика веб приложения распределена между сервером и клиентом, хранение данных осуществляется, преимущественно, на сервере, обмен… … Википедия

    Тип Общество с ограниченной ответственностью Год основания … Википедия

    Веб приложение клиент серверное приложение, в котором клиентом выступает браузер, а сервером веб сервер. Браузер может являться реализацией так называемых тонких клиентов. Браузер способен отображать веб страницы и, как правило, входит в состав… … Википедия

    Веб приложение клиент серверное приложение, в котором клиентом выступает браузер, а сервером веб сервер. Браузер может являться реализацией так называемых тонких клиентов. Браузер способен отображать веб страницы и, как правило, входит в состав… … Википедия

БД, работающие по технологии ФАЙЛ-СЕРВЕР;

БД, работающие по технологии КЛИЕНТ-СЕРВЕР.

Файл-сервер


- Обращение к БД (запрос)
- Перекачка данных с блокировкой доступа других пользователей
- Обработка данных на компьютере пользователя

Для наглядности рассмотрим конкретные примеры. Допустим, Вам необходимо просмотреть отправленные платежные поручения за период с 19 по 25 мая на сумму 5000 рублей. Пользователю необходимо будет запустить на своем компьютере клиентское приложение, работающее в БД с платежными поручениями, и ввести нужные критерии отбора. После чего на Ваш компьютер перекачается с сервера базы данных и загрузится в оперативную память файл, содержащий все документы данного вида за весь период на любые суммы. Запущенное на компьютере пользователя клиентское приложение, работающее с БД, само проведет обработку этой информации (отсортирует их), после чего выдаст ответ (на экране появится список платежных поручений, удовлетворяющих Вашим критериям). После этого Вы выберете нужное платежное поручение и попытаетесь отредактировать (изменить) в нем одно поле - например, дату. Во время редактирования происходит блокировка источника данных, то есть всего файла, содержащего этот документ. Это означает, что файл будет либо совсем не доступен остальным пользователям, либо доступен только в режиме просмотра. Причем подобного рода захват происходит даже не на уровне записи, то есть одного документа, а заблокированным является целый файл - то есть вся таблица, содержащая аналогичные документы. Только после полной обработки этого поля и выхода из режима редактирования данный файл платежных поручений будет разблокирован от захвата пользователем. Если же данные хранятся в более объемных объектах, например, в одном файле содержатся платежные поручения и о поступлении средств, и об отправке, то еще большая часть информации будет не доступна. Вы будете работать с одним полем "дата" в одном документе - остальные сотрудники предприятия будут ждать, пока Вы не закончите.

Недостатки ФАЙЛ-СЕРВЕРНОЙ системы очевидны:

    Очень большая нагрузка на сеть, повышенные требования к пропускной способности. На практике это делает практически невозможной одновременную работу большого числа пользователей с большими объемами данных.

    Обработка данных осуществляется на компьютере пользователей. Это влечет повышенные требования к аппаратному обеспечению каждого пользователя. Чем больше пользователей, тем больше денег придется потратить на оснащение их компьютеров.

    Блокировка данных при редактировании одним пользователем делает невозможной работу с этими данными других пользователей.

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

    Клиент-сервер

    Обработка запроса одного пользователя:
    - Обращение к БД (SQL-запрос)
    - Передача ответа - результата обработки


    При необходимости произвести обработку информации, хранящейся в БД, запущенное на компьютере пользователя клиентское приложение, работающее с БД, формирует запрос на языке SQL (название от начальных букв - Structured Query Language). Сервер базы данных принимает запрос и обрабатывает его самостоятельно. Никакой массив данных (файл) по сети не передается. После обработки запроса на компьютер пользователя передается только результат - то есть, в предыдущем примере, - список платежных поручений, удовлетворяющих нужным критериям. Сам же файл, в котором хранились данные, послужившие источником для обработки, остается незаблокированным для доступа самого сервера по запросам других пользователей.

    В серьезных клиент-серверных СУБД существуют дополнительные механизмы, снижающие нагрузку на сеть, снижающие требования к пользовательским компьютерам. В качестве примера приведем хранимые процедуры - то есть целые программы обработки данных, хранящихся в БД. В этом случае от пользователя к серверу не передается даже SQL выражения - передается вызов функции с параметрами вызова. Таким образом, рабочее место пользователя еще сильнее упрощается, логика работы программы переносится на сервер. Пользовательское место становится всего лишь средством отображения информации. Все это означает дальнейшее снижение нагрузки на сеть и пользовательские рабочие станции.

    Таким образом, все вышеперечисленные недостатки ФАЙЛ-СЕРВЕРНОЙ схемы устраняются в архитектуре КЛИЕНТ-СЕРВЕР:

      Массивы данных не перекачиваются по сети от сервера БД на компьютер пользователя. Требования к пропускной способности сети понижаются. Это делает возможным одновременную работу большого числа пользователей с большими объемами данных.

      Обработка данных осуществляется на сервере БД, а не в компьютере пользователей. Что позволяет использовать более простые, а значит, дешевые компьютеры на клиентских местах.

      Блокировки (захвата) данных одним пользователем не происходит.

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

      Рассмотрев отличие ФАЙЛ-СЕРВЕРА от КЛИЕНТ-СЕРВЕРА, можно завершить рассмотрение понятия "хранилище информации". Важно подчеркнуть, что от вида используемой СУБД во многом зависит работа корпоративной системы. Совершенно очевидно, что для крупных предприятий, с большим количеством пользователей, с огромным числом записей в БД, файл-серверная схема совершенно неприемлема. С другой стороны, отличия в базах данных есть и по другим параметрам и возможностям:

        типам данных, которые могут храниться в БД (числа, даты, текст, рисунки, видео, звук и т.д);

        по организуемым самой БД технологиям доступа к данным в базе и уровню защиты информации от несанкционированного доступа;

        по предоставляемым средствам и методикам разработки, которые могут быть применены для проектирования какой-либо информационной системы на основе данной БД;

        по предоставляемым средствам и методикам анализа информации (данных), которые могут быть применены в информационной системы на основе данной БД;

        по надежности и устойчивости, то есть (грубо) количеству записей (заполненных полей) в БД, при которых обеспечивается надежная и бесперебойная возможность доступа, изменения, анализа информации в БД;

        по быстродействию - времени, затраченному на доступ и обработку информации;

        по возможности организации работы на компьютерах разных производителей, то есть по совместимости с другими платформами и операционными системами;

        по уровню поддержки (сервиса), предоставляемого разработчиком базы данных или его авторизованным дилером;

        по наличию хороших средств создания приложений, использующих данную базу данных и т.д.

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

БД , на структурном языке запросов SQL (Structured Query Language ), являющемся промышленным стандартом в мире реляционных БД . Удаленный сервер принимает запрос и переадресует его SQL -серверу БД . SQL - сервер – специальная программа , управляющая удаленной базой данных. SQL - сервер обеспечивает интерпретацию запроса, его выполнение в базе данных, формирование результата выполнения запроса и выдачу его приложению-клиенту. При этом ресурсы клиентского компьютера не участвуют в физическом выполнении запроса; клиентский компьютер лишь отсылает запрос к серверной БД и получает результат, после чего интерпретирует его необходимым образом и представляет пользователю. Так как клиентскому приложению посылается результат выполнения запроса, по сети "путешествуют" только те данные, которые необходимы клиенту. В итоге снижается нагрузка на сеть . Поскольку выполнение запроса происходит там же, где хранятся данные (на сервере), нет необходимости в пересылке больших пакетов данных. Кроме того, SQL - сервер , если это возможно, оптимизирует полученный запрос таким образом, чтобы он был выполнен в минимальное время с наименьшими накладными расходами [ [ 3.2 ] , [ 3.3 ] ]. системы представлена на рис. 3.3 .

Все это повышает быстродействие системы и снижает время ожидания результата запроса. При выполнении запросов сервером существенно повышается степень безопасности данных, поскольку правила целостности данных определяются в базе данных на сервере и являются едиными для всех приложений, использующих эту БД . Таким образом, исключается возможность определения противоречивых правил поддержания целостности. Мощный аппарат транзакций, поддерживаемый SQL -серверами, позволяет исключить одновременное изменение одних и тех же данных различными пользователями и предоставляет возможность откатов к первоначальным значениям при внесении в БД изменений, закончившихся аварийно [ [ 3.2 ] , [ 3.3 ] ].


Рис. 3.3. Архитектура "клиент – сервер"

  • Существует локальная сеть, состоящая из клиентских компьютеров, на каждом из которых установлено клиентское приложение для работы с БД.
  • На каждом из клиентских компьютеров пользователи имеют возможность запустить приложение. Используя предоставляемый приложением пользовательский интерфейс, он инициирует обращение к СУБД, расположенной на сервере, на выборку/обновление информации. Для общения используется специальный язык запросов SQL , т.е. по сети от клиента к серверу передается лишь текст запроса.
  • СУБД инициирует обращения к данным, находящимся на сервере, в результате которых на сервере осуществляется вся обработка данных и лишь результат выполнения запроса копируется на клиентский компьютер. Таким образом СУБД возвращает результат в приложение.

Рассмотрим, как выглядит разграничение функций между сервером и клиентом.

  • Функции приложения-клиента:
    • Посылка запросов серверу.
    • Интерпретация результатов запросов, полученных от сервера.
    • Представление результатов пользователю в некоторой форме (интерфейс пользователя).
  • Функции серверной части:
    • Прием запросов от приложений-клиентов.
    • Интерпретация запросов.
    • Оптимизация и выполнение запросов к БД.
    • Отправка результатов приложению-клиенту.
    • Обеспечение системы безопасности и разграничение доступа.
    • Управление целостностью БД.
    • Реализация стабильности многопользовательского режима работы.

В архитектуре " клиент – сервер " работают так называемые "промышленные" СУБД . Промышленными они называются из-за того, что именно СУБД этого класса могут обеспечить работу информационных систем масштаба среднего и крупного предприятия, организации, банка. К разряду промышленных СУБД принадлежат MS SQL Server , Oracle , Gupta, Informix , Sybase , DB2 , InterBase и ряд других [ [ 3.2 ] ].

Как правило, SQL - сервер обслуживается отдельным сотрудником или группой сотрудников (администраторы SQL -сервера). Они управляют физическими характеристиками баз данных, производят оптимизацию, настройку и переопределение различных компонентов БД , создают новые БД , изменяют существующие и т.д., а также выдают привилегии (разрешения на доступ определенного уровня к конкретным БД , SQL -серверу) различным пользователям [ [ 3.2 ] ].

Рассмотрим основные достоинства данной архитектуры по сравнению с архитектурой " файл - сервер ":

  • Существенно уменьшается сетевой трафик.
  • Уменьшается сложность клиентских приложений (большая часть нагрузки ложится на серверную часть), а, следовательно, снижаются требования к аппаратным мощностям клиентских компьютеров.
  • Наличие специального программного средства – SQL-сервера – приводит к тому, что существенная часть проектных и программистских задач становится уже решенной.
  • Существенно повышается целостность и безопасность БД.

К числу недостатков можно отнести более высокие финансовые затраты на аппаратное и программное обеспечение , а также то, что большое количество клиентских компьютеров, расположенных в разных местах, вызывает определенные трудности со своевременным обновлением клиентских приложений на всех компьютерах-клиентах. Тем не менее, архитектура " клиент – сервер " хорошо зарекомендовала себя на практике, в настоящий момент существует и функционирует большое количество БД , построенных в соответствии с данной архитектурой.

3.4. Трехзвенная (многозвенная) архитектура "клиент – сервер".

Трехзвенная (в некоторых случаях многозвенная ) архитектура (N- tier или multi- трехзвенной архитектуры ? Теперь при изменении бизнес-логики более нет необходимости изменять клиентские приложения и обновлять их у всех пользователей. Кроме того, максимально снижаются требования к аппаратуре пользователей.

Итак, в результате работа построена следующим образом:

  • База данных в виде набора файлов находится на жестком диске специально выделенного компьютера (сервера сети).
  • СУБД располагается также на сервере сети.
  • Существует специально выделенный сервер приложений, на котором располагается программное обеспечение (ПО) делового анализа (бизнес-логика) [ [ 3.1 ] ].
  • Существует множество клиентских компьютеров, на каждом из которых установлен так называемый "тонкий клиент" – клиентское приложение, реализующее интерфейс пользователя.
  • На каждом из клиентских компьютеров пользователи имеют возможность запустить приложение – тонкий клиент. Используя предоставляемый приложением пользовательский интерфейс, он инициирует обращение к ПО делового анализа, расположенному на сервере приложений.
  • Сервер приложений анализирует требования пользователя и формирует запросы к БД. Для общения используется специальный язык запросов SQL , т.е. по сети от сервера приложений к серверу БД передается лишь текст запроса.
  • СУБД инкапсулирует внутри себя все сведения о физической структуре БД, расположенной на сервере.
  • СУБД инициирует обращения к данным, находящимся на сервере, в результате которых результат выполнения запроса копируется на сервер приложений.
  • Сервер приложений возвращает результат в клиентское приложение (пользователю).
  • Приложение, используя пользовательский интерфейс, отображает результат выполнения запросов.