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

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

Рекомендуемая последовательность действий при завершении связи такова. Сначала клиент завершает отправку данных через сокет, вызывая функцию shutdown с параметром SD_SEND. Сервер при этом получает событие FD_CLOSE. Сервер отсылает данные клиенту (при этом клиент получает одно или несколько событий FD_READ), а затем также завершает отправку данных с помощью shutdown с параметром SD_SEND. Клиент при этом получает событие FD_CLOSE, в ответ на которое закрывает сокет с помощью closesocket. Сервер, в свою очередь, сразу после вызова shutdown также вызывает closesocket. В листинге 2.49 приведен пример кода сервера, использующего асинхронные сокеты. Сервер работает в режиме запрос-ответ, т. е. посылает какие-то данные клиенту только в ответ на его запросы. Константа WM_SOCKETEVENT, определенная в коде для сообщений, связанных с сокетом, может, в принципе, иметь и другие значения.

Листинг 2.49. Пример простого сервера на асинхронных сокетах

unit Unit1;

interface

uses

 Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, WinSock;

const

 WM_SOCKETEVENT = WM_USER + 1;

type

 TForm1 = class(TForm)

 procedure FormCreate(Sender: TObject);

 procedure FormDestroy(Sender: TObjеct);

 private

 ServSock: TSocket;

procedure WMSocketEvent(var Msg: TMessage); message WM_SOCKETEVENT;

 end;

var

 Form1: TForm1;

implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);

var

 Data: TWSAData;

 Addr: TSockAddr;

begin

 WSAStartup($101, Data);

 // Обычная последовательность действий по созданию сокета,

 // привязке его к адресу и установлению на прослушивание

 ServSock:= socket(AF_INET, SOCK_STREAM, 0);

 Addr.sin_family:= AF_INET;

 Addr.sin_addr.S_addr:= INADDR_ANY;

 Addr.sin_port:= htons(3320);

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

 bind(ServSock, Addr, SizeOf(Addr));

 listen(ServSock, SOMAXCONN);

 // Перевод сокета в асинхронный режим. Кроме события FD_ACCEPT

 // указаны также события FD_READ и FD_CLOSE, которые никогда не

 // возникают на сокете, установленном в режим прослушивания.

 // Это сделано потому, что сокеты, созданные с помощью функции

 // accept, наследуют асинхронный режим, установленный для

 // слушающего сокета. Таким образом, не придется вызывать

 // функцию WSAAsyncSelect для этих сокетов — для них сразу

 // будет назначен обработчик событий FD_READ и FD_CLOSE.

 WSAAsyncSelect(ServSock, Handle, WM_SOCKETEVENT, FD_READ or FD_ACCEPT or FD_CLOSE);

end;

procedure TForm1.FormDestroy(Sender: TObject);

begin

 closesocket(ServSock);

 WSACleanup;

end;

procedure TForm1.WMSocketEvent(var Msg: TMessage);

var

 Sock: TSocket;

 SockError: Integer;

begin

 Sock:= TSocket(Msg.WParam);

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

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

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

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

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

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