Читаем О чём не пишут в книгах по Delphi полностью

Теперь перейдем к написанию клиента. Пример этого клиента находится на компакт-диске в папке SimpleClient, главное окно показано на рис. 2.4. Клиент должен вызывать только одну функцию, которая реально может блокировать вызвавшую ее нить, — функцию recv. Но по нашему протоколу сервер не посылает клиенту ничего по собственной инициативе, он только отвечает на сообщения клиента. Следовательно, клиент не должен быть всегда готов принять сообщение, он его принимает только после отправки своего. В простых случаях, когда сообщение имеет небольшой размер, а формирование ответа на сервере не требует длительной работы, мы можем считать, что попытка получения ответа от сервера сразу же после отправки ему сообщения в подавляющем большинстве случаев не будет блокировать работу клиента, а оставшееся незначительное количество случаев считаем форс-мажором и допускаем, что в такой ситуации блокирование будет допустимо. На практика заметить это блокирование можно будет только тогда, когда сервер не будет должным образом отвечать на сообщения или связь с ним будет потеряна. Для простого клиента с невысокими требованиями к надежности такое упрощение вполне допустимо и вполне может быть использовано на практике. А в дальнейшем мы познакомимся со средствами библиотеки сокетов, позволяющими писать программы, в которых работа с сокетами никогда не приводит к блокировке.

Рис. 2.4. Главное окно программы SimpleClient

Таким образом, наш клиент будет очень простым: по кнопке Соединиться он будет соединяться с сервером, по кнопке Отправить — отправлять серверу сообщение и дожидаться ответа. Третья кнопка, Отсоединиться, служит для корректного завершения работы с сервером. Рассмотрим эти действия подробнее.

При соединении с сервером клиент должен создать сокет и вызвать функцию connect. Здесь мы не можем создать сокет один раз и потом пользоваться им на протяжении всего времени работы клиента, т. к. после закрытия соединения (неважно, корректного или из-за ошибки) сокет больше нельзя использовать. Поэтому при установлении соединения каждый раз приходится создавать новый сокет. Обработчик нажатия кнопки Соединиться приведен в листинге 2.16.

Листинг 2.16. Обработчик нажатия кнопки Соединиться

procedure TSimpleClientForm.BtnConnectClick(Sender: TObject);

var

 // Адрес сервера

 ServerAddr: TSockAddr;

begin

 // Формируем адрес сервера, к которому нужно подключиться

 FillChar(ServerAddr.sin_zero, SizeOf(ServerAddr.sin_zero), 0);

 ServerAddr.sin_family:= AF_INET;

 ServerAddr.sin_addr.S_addr:= inet_addr(PChar(EditIPAddress.Text));

 // Для совместимости со старыми версиями Delphi приводим

 // константу INADDR_ANY к типу u_long

 if ServerAddr.sin_addr.S_addr:= u_long(INADDR_NONE)then

 begin

MessageDlg('Синтаксическая ошибка в IР-адресе', mtError, [mbOK], 0);

 Exit;

 end;

 try

ServerAddr.sin_port:= htons(StrToInt(EditPort.Text));

 // Создание сокета

FSocket:= socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

if FSocket = INVALID_SOCKET then

begin

MessageDlg('Ошибка при создании сокета: '#13#10 +

 GetErrorString, mtError, [mbOK], 0);

 Exit;

 end;

 // Подключение к серверу

if connect(FSocket, ServerAddr, SizeOf(ServerAddr)) < 0 then

 begin

MessageDlg('Ошибка при установлении подключения: '#13#10 +

 GetErrorString, mtError, [mbOK], 0);

// Так как сокет был успешно создан,

 // в случае ошибки его нужно удалить

 closesocket(FSocket);

 FSocket:= 0;

 Exit;

 end;

// Включаем режим "Соединение установлено"

 OnConnect;

 except

 on EConvertError do

 // Это исключение может возникнуть только в одном месте -

 // при вызове StrToInt(EditPort.Text)

MessageDlg('"' + EditPort.Text + '"не является целым числом',

 mtError, [mbOK], 0);

Перейти на страницу:

Похожие книги

1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных