Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
26
Добавлен:
30.04.2019
Размер:
78.85 Кб
Скачать

Объект tServerWinSocket

На уровне этого объекта ведется список соединений с клиентскими сокетами, содержащийся в свойстве:

property Connections[Index: Integer]: TCustomWinSocket;

Общее число соединений (и число элементов в свойстве connections) равно значению свойства:

property ActiveConnections: Integer;

Этим списком и счетчиком удобно пользоваться для рассылки всем клиен­там какой-нибудь широковещательной информации, например:

for i:=0 to ServerSocket.Socket.ActiveConnections-1 do ServerSocket.Socket.Connections[i].SendText('Hi!') ;

Тип сервера (блокирующий/неблокирующий) задается свойством

type TServerType = (stNonBlocking, StThreadBlocking) ;

property ServerType: TServerType;

Поскольку сервер, который блокируется каждым чтением/записью, предста­вить себе трудно, разработчики фирмы Inprise пошли таким путем. Блоки­рующий режим заменен режимом stThreadBlocking. В этом случае при ус­тановлении каждого нового соединения запускается отдельный программный поток (объект класса TServerClientThread). Он отвечает за связь с отдельным клиентом, и его блокировка не влияет на работу осталь­ных соединений.

Если вы не хотите порождать TServerClientThread, а хотите описать свой класс потока и использовать его для работы с сокетом, вам нужно создать обработчик события:

property OnGetThread: TGetThreadEvent;

type TGetThreadEvent = procedure (Sender: TObject; ClientSocket: TServerClientWinSocket; var SocketThread: TServerClientThread) of object;

B отличие от stThreadBlocking, тип stNonBlocking своим поведением ничем не отличается от описанного выше — операции происходят асинхронно, а программист должен лишь описать реакцию на события, возникающие в момент их окончания.

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

Свойство:

property ThreadCacheSize: Integer;

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

property ActiveThreads: Integer;

property IdleThreads: Integer;

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

Старт и завершение потока, работающего с сокетом, обрамлены событиями:

property OnThreadStart: TThreadNotifyEvent;

property OnThreadEnd: TThreadNotifyEvent;

type TThreadNotifyEvent = procedure (Sender: TObject; Thread: TServerClientThread) of object;

Чтобы из­бежать ситуации тупиков или гонок при работе с сокетами, имеются два метода:

procedure Lock;

procedure Unlock;

Если вами предусмотрен код, который может вызвать проблемы в многоза­дачной среде, заключите его между вызовами методов Lock и Unlock – в это время остальные потоки, работающие с сокетами, будут блокированы. Методы чтения и записи для блокирующего и неблокирующего режима существенно отличаются. Рассмотрим сначала те, что предназначены для неблокирующего (асинхронного) режима.

Средства для организации чтения представлены группой из трех методов:

  • function ReceiveLength: Integer; - возвращает число байт, которые могут быть приняты в ответ на оповещение клиента о передаче,

  • function ReceiveText: string; - возвращает прочитанную из сокета текстовую строку,

  • function ReceiveBuf(var Buf; Count: Integer): Integer; - возвращает данные, прочитанные из сокета в буфер Buf, в количестве Count байт

Аналогично, методы:

function SendBuffer(Buf; Count: Integer): Integer;

procedure SendTextfConst(const S: string);

function SendStream(AStream: TStream) : Boolean;

посылают клиенту буфер, текстовую строку и поток данных. В дополнение к этому метод:

function SendStreamThenDropfAStream: TStream) : Boolean; посылает клиенту поток данных и завершает соединение.

Соседние файлы в папке ПИУС