КАТЕГОРИИ: Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748) |
Клиент-серверное взаимодействие посредством использования сокетов 1 страница
Давайте присмотримся — что реально предлагают нам описанные выше средства клиент-серверного обмена данными? Браузеры автоматически формируют графическое отображение Web-страниц, посланных сервером. Для стандартного Web-сайта этого оказывается вполне достаточным, но что делать, когда нужно строить клиент-серверное взаимодействие, основанное на передаче/приеме данных, которые не являются HTML-документами? Или нужно создавать решения, в рамках которых вообще нет места браузерам, и клиентская программа сама должна формировать представление информации? В таких случаях прибегают к сокетам. Сокеты — это объекты, которые инкапсулируют в себе все необходимые средства для обмена данными в сетях Интернет/интранет. Эти объекты сами создают соединения и посылают/принимают данные, что позволяет программисту избавиться от многих забот и организовать взаимодействие между различными программными компонентами в масштабах сетей так же легко, как, например, чтение и запись в файл. Итак, рассмотрим эти объекты подробнее.
Клиентский сокет Этот объект предназначен для установления связи с сервером. Точнее, с серверным сокетом, даже если этот сокет выполнен на другом языке программирования. Нахождение нужного сервера осуществляется в сети по его имени, либо IP-адресу. После установления соединения программа может взаимодействовать с сервером, а именно — посылать и принимать данные. Интересно то, что эти данные могут быть произвольного типа. Значки компонентов TServerSocket И TClientSocket, используемые сервером и клиентом в сетевом взаимодействии, показаны на рис. 13.1.
Рис. 13.1. Размещение компонентов TServerSocket и TClientSocket Работать с клиентским сокетом довольно просто. Достаточно указать сервер, его порт, на котором расположена интересуемая служба, а после того, активизировать сокет. После установки соединения вам становятся доступны методы, позволяющие осуществлять прием/передачу данных, которые приведены в табл. 13.1. Таблица 13.1. Некоторые свойства объектов класса TClientSocket
Обратите внимание, что при использовании сокетов программисту предоставляются альтернативные пути идентификации сервера. Часто в одноранговых, с точки зрения топологии, локальных сетях применяются протоколы типа NetBEUI — базовый протокол производства Microsoft или IPX/SPX — сети, основанные на технологиях Novell. В этих сетях компьютеры не имеют своих IP-адресов и идентифицируются по имени компьютера. Чтобы работать в таких сетях, нужно вместо поля Address устанавливать значение host. Если создаваемое приложение будет работать в IP-сетях, то лучше определить параметр Address по следующей причине. Даже если в сети работает служба DNS (см. гл. 1), то все равно сокетные компоненты используют IP-адреса для указания конечного получателя данных. Эти адреса ими извлекаются из запросов к DNS, сопоставляющих имени — IP-адрес. Этот процесс требует определенного времени и сопряжен с возможностью возникновения ошибок. Поэтому лучше сразу указывать IP-адрес машины-сервера. Если приложение будет развернуто в сети Ethernet, не использующей DNS, то просто необходимо указывать IP-адрес.
Перечисленные свойства устанавливают общие характеристики сокета. Основную же нагрузку при клиент-серверном взаимодействии несет на себе объект, указанный в параметре socket. Наиболее часто используемые методы объектов класса iciientsocket указаны в табл. 13.2. Таблица 13.2. Некоторые методы объектов класса Tdientsocket
Как видим, эти методы не предоставляют прямого интерфейса для отправки или получения данных, они находятся все в том же объекте socket. События объектов класса Tdientsocket описаны в табл. 13.3. Таблица 13.3. События объектов класса Tdientsocket
Как видим, данный объект инкапсулирует только свойства и методы касательные соединения. Для непосредственной работы с данными служит объект класса TCiientwinSocket, доступ к которому может осуществляться посредством Свойства Socket объекта ClientSocket.
Класс TClientwinSocket Этот класс инкапсулирует в себе свойства и методы, обеспечивающие взаимодействие с сервером. Основные свойства объектов данного класса представлены в табл. 13.4. Таблица 13.4. Некоторые свойства объектов класса TCiientwinSocket
Как видно из табл. 13.4, свойства объектов класса TCiientwinSocket более детально описывают состояние сокета, что позволяет программе анализировать его и определять свои дальнейшие действия. Методы таких объектов описаны в табл. 13.5. Таблица 13.5. Некоторые методы объектов класса TCiientwinSocket
Данный объект предоставляет все возможности для отправки/приема данных при использовании типа ctNonBiocking сокета. Как видим, здесь есть два сорта операторов чтения и записи, работающие с буферами или строковыми переменными. Кроме того, присутствуют эквивалентные методы для отправки данных. В случае, когда нужно считать данные в поток или отправить содержимое потока серверу, используется тип последнего TWinSocketStream, который создается на основе объекта ClientWinSocket. Методы объектов класса TWinSocketStream представлены в табл. 13.6.
Таблица 13.6. Некоторые методы объектов класса TWinSocketStream
Использование потока допустимо в случае, когда клиент принадлежит к типу ctBiocking. При ассоциации потока с объектом clientwinsocket чтение/запись происходит уже не непосредственно из/в сокета, а в созданном потоке, что позволяет работать с ним, как, например, с потоком файлового ввода/вывода. При создании приложения, которое будет взаимодействовать с сервером посредством сокетов, прежде всего,, нужно внести данные о сервере в свойства объекта clientsocket. После этого, через свойство socket можно получить доступ к соответствующему объекту clientwinsocket. Если используется асинхронная передача информации, т. е. клиент имеет тип ctNonBiocking, то посредством вызова необходимых методов можно принимать/отправлять данные клиенту. В противном случае, с данным сокетом необходимо сопоставить поток, который и будет осуществлять прием/передачу данных. При использовании этого типа клиента события onRead и onWrite, разумеется, не имеют никакого смысла, и поэтому не возникают.
Пример реализации сокетного клиента Вернемся к примеру, который мы начали реализовывать в предыдущей главе. А именно, речь шла об ActiveX-форме, которая должна отображать данные заказа, предоставлять возможность для распечатки счета и отправлять на сервер реквизиты покупателя, с целью последующего их сохранения в базе данных фирмы. В этом случае, уже неважно, что речь идет об ActiveX-элементах управления. Если бы форма не внедрялась в Web-страницу, то работа с сокетами была бы полностью аналогична. Для того чтобы добавить эти интерактивные возможности, нужно, как обычно, создавать два компонента программы — на стороне сервера и стороне клиента. Сначала реализуем клиентскую часть. Поместим в проект компонент clientsocket. После этого нужно установить его параметры. Адрес сервера, установленного на локальную машину, как отмечалось выше 127.0.0.1, имя хоста — localhost или имя компьютера в сети. Наше приложение, работая на стороне клиента, лишь однажды отправит данные через сокет, поэтому наиболее простым вариантом его реализации является применение метода sendText, без использования потоков в программе. Исходя из этого, тип сокета установим в ctNonBiocking. Обычно, Web-сервер имеет номер сетевого порта равный 80. Это значит, что наша серверная программа должна иметь другой сетевой порт, например — 800. Главное, чтобы при назначении номера порта не возникло конфликтов с другими сетевыми службами из-за одинаковых номеров. Таким образом, присвоим свойству Port значение 800. После инициации соединения с сервером, например, путем установки свойства Active в True, сокет автоматически ищет соответствующий ресурс, и после его нахождения проверяет готовность серверного сокета к приему данных. Как только такое уведомление получено (на низком сетевом уровне), сокет инициирует событие ciientsocketwrite. Как раз в соответствующую данному событию процедуру мы и поместим код, отсылающий содержимое заполненных полей на сервер. На самом деле, можно по-разному закодировать данные. Все зависит от вкуса и конкретных привычек программиста. Однако существует тенденция к усилению роли стандартного использования данных путем их представления в формате extensible Markup Language (в дальнейшем — XML). Этот язык представляет собой набор базовых требований к реализациям собственных средств разметки с целью унификации документооборота и обмена данными. Поясню вышесказанное. Предположим, что наша фирма "Два кирпича" имеет пять региональных представительств. Каждое из этих представительств, в свою очередь продает получаемые материалы, через свои Web-сайты. Более того, несколько раз в день головная фирма рассылает представительствам информацию об ассортименте и ценах на товары в виде прайс-листов. Разумеется, все изменения должны автоматически вноситься в базу данных фирмы и содержимое сайта. Ручное внесение изменений недопустимо в связи с необходимостью постоянного контроля над целостностью данных, что при большом количестве позиций крайне затруднительно. Следует искать автоматизированные решения. Для обеспечения простого взаимодействия с информационными системами конкретных представительств необходимо иметь стандарт представления данных. В нашем случае, с одной стороны, информационная система должна анализировать содержимое документа с целью выявления нужных данных, которые будут внесены в БД фирм, а с другой стороны, документ, составленный по этим правилам, должен иметь более широкие возможности для визуального представления данных, нежели простая таблица. Понятно, что возможности HTML достаточно скудно реализуют выдвинутые требования, поскольку отражают лишь форматирование данных. Невозможно прямо указать тип передаваемых данных, назначить им какие-либо специальные атрибуты. Использование форматирования, базирующегося на языке XML, позволяет передавать не только сами данные, но и указывать их принадлежность. Рассмотрение этого языка выходит за рамки данной книги, но в примере мы используем следующие соглашения касательно формата представления передаваемых данных.
На основании этого представления нам (в смысле программирования серверной части) будет легко разобраться, какие сведения к чему относятся. Реализуем процедуру шифрования данных и последующей их отправки (листинг 13.1). Объект клиентский сокет назовем cisock. Листинг 13.1. Реализация процедуры шифрования и отправки данных через сокетное соединение примера procedure Tshop.ClSockWrite(Sender: TObject; Socket: TCustomWinSocket); begin Content:='<CUSTNAME>'+custname.text+ '</CUSTNAMEXCUSTADDRESS>'+ custaddress.Text+'</CUSTADDRESSXCUSTBANK>' +custbank.Text+'</CUSTBANK>'; Cisock.Socket.SendText(content); end; Чтобы использовать шаблон для введения кода процедуры, вызываемой как отклик на событие, нужно сделать двойной щелчок мышью в названии процедуры в окне Object Inspector напротив соответствующего события. В данном случае, это событие OnWrite. Как видим, процесс обмена данными через сокеты предельно прост, несмотря на то, что его реализация на низком уровне представляет собой очень содержательную задачу. Вот как проявляются фантастические возможности RAD-среды Delphi! Теперь осталось только вписать одну строчку в процедуру Tshop.printbtnciick, а именно clsock.active:=true Как только пользователь нажмет на кнопку Печать, сокет произведет попытку соединения с сервером. В случае если соединение случится, то пойдет выполнение процедуры cisockwrite. В противном случае, возникнет исключительная ситуация. При разработке реальных проектов нужно всегда помещать вызов метода Open в конструкцию, обеспечивающую корректную работу с исключительными ситуациями try... except.
Серверный сокет Серверный сокет предполагает обмен данными с клиентами. В принципе, от клиентской реализации он отличается тем, что способен работать с несколькими клиентами одновременно. На базе серверного сокета можно создавать программы — серверы, которые предоставляют возможность внедрять собственные протоколы верхнего уровня, т. е. реализовывать различные схемы обмена данными. Свойства объектов класса TServerSocket представлены в табл. 13.7. Таблица 13.7. Основные свойства объектов класса TServerSocket
Аналогично клиентскому сокету, в сетевом сокете основную функциональную нагрузку несет на себе объект, указанный в поле socket, который будет описан чуть позже. Наиболее часто используемые методы объектов класса TServerSocket описаны табл. 13.8. Таблица 13.8. Некоторые методы объектов класса TServerSocket
Аналогично клиентскому сокету, вызов метода open устанавливает значения поля Active в true, а вызов close — в false. События, которые могут возникать у объектов класса TServerSocket, приведены в табл. 13.9. Таблица 13.9. События объектов класса TServerSocket
Как и в случае с клиентским сокетом, для работы с сокетными подключениями создается объект, доступный посредством свойства Socket. Необходимо учитывать, что серверный сокет может обслуживать несколько подключений одновременно, и поэтому для каждого подключения существует свой экземпляр объекта, предоставляющий сетевые сервисы. Графически последовательность выбора свойств объектов для доступа к непосредственному соединению изображена на рис. 13.2. Рис. 13.2. Алгоритм обращения к полям объектов для доступа непосредственно к соединению Обратите внимание, что, как и в случае клиентского сокета, объект ServerSocket служит для установления и обслуживания общих свойств соединения, но в нем свойство socket указывает не на конечное соединение, а на другой объект — serverwinsocket, который в свою очередь осуществляет менеджмент соединений. Свойства последнего сведены в табл. 13.10. Таблица 13.10. Некоторые свойства объекта serverNinSocket
Handle окна, или другого объекта, это целое число, которое им присваивается операционной системой Windows. При обычном создании окон с помощью Delphi программисту незачем использовать этот параметр, но если окна создаются путем прямого вызова API-функций или модернизируются ими, к примеру, делаются полупрозрачными или овальными, то параметр Handle используется повсеместно. Кроме того, если вы хотите работать напрямую с системой Windows, окнами и процессами другого приложения, то индексация нужных объектов также осуществляется путем использования этих параметров. Методы объекта serverwinSocket сведены в табл. 13.11. Таблица 13.11. Некоторые методы объекта ServerwinSocket
Легко заметить, что основные методы, предназначенные для приема/отправки данных, одинаковы у объектов класса TServerwinSocket и TClientwinSocket. Связано это с тем, что они оба являются наследниками класса TCustonwinSocket. Естественно, что и работа с данными методами объектов указанных классов одинакова. Поэтому, чтобы узнать, как читать и отправлять данные, используя серверный сокет, загляните в соответствующий раздел описания клиентского сокета. События объектов класса TServerwinSocket и TServerSocket практически одинаковы, поэтому на них мы подробно останавливаться не будем.
Пример реализации сонетного сервера Как обычно, вернемся к нашему примеру, который мы реализуем на протяжении изложения всего материала книги. В результате выполнения предыдущих примеров у нас получился клиентский модуль, который отправляет на сервер информацию о клиенте с целью последующего ее сохранения в БД фирмы. Мы можем создать сокетный сервер, используя обычные визуальные средства Delphi. Это освободит нас от обработки множества событий. По сути, серверные приложения, базирующиеся на сокетах, создаются точно так же, как и клиентские. Отличие заключается в том, что после установки всех свойств и активизации объекта клиентский сокет пытается установить соединение с сервером, а серверный опрашивает сетевой порт. Как бы там ни было, все, что нужно сделать в примере, — это поместить объект в форму, установить его свойства и активизировать. Только нужно поместить обработчик события OnClientRead.
Дата добавления: 2014-12-29; Просмотров: 863; Нарушение авторских прав?; Мы поможем в написании вашей работы! Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет |