Глубины Indy

       

Исходный код


Сервер состоит из двух частей, Server.pas и BSOD.pas. BSOD.pas содержит форму, которая используется для показа BSOD экрана. BSOD.pas не содержит Indy кода и поэтому не рассматривается здесь.

Server.pas – это главная форма приложения и содержит один UDP сервер. Свойство port установлено в 6001 и свойство active установлено в True. Когда приложение запускается, то оно немедленно начинает слушать порт для входящих UDP пакетов.

Как ранее обсуждалось UDP подобен пейджеру. Поскольку ему не требуется соединение для приема данных. Пакеты данных просто появляются как один кусок. Для каждого принятого UDP пакета, UDP сервер возбуждает событие OnUDPRead. Больше никаких других событий не требуется для реализации UDP сервера. Когда возбуждается событие OnUDPRead, полный пакет уже принят и готов к использованию.

Событию OnUDPRead передаются три аргумента:

1. ASender: TObject – это компонент, который возбудил данное событие. Это применимо только если будет создано несколько UDPServers серверов и используют один и тот же метод для события. Это очень редко нужно.

2.      AData: TStream – это основной аргумент и он содержит сам пакет. UDP пакеты могут содержать текст и/или двоичные данные. Поэтому Indy предоставляет их в виде потока. Для доступа к данным, просто используйте методы read класса TStream.

3.      ABinding: TIdSocketHandle – этот аргумент пригоден для получения расширенной информации. Это востребовано, если используется связывание (bindings). Вот пример как выглядит событие OnUDPRead в RBSOD сервере:

procedure TformMain.IdUDPServer1UDPRead(Sender: TObject; AData: TStream; ABinding: TIdSocketHandle);

var

  LMsg: string;

begin

  if AData.Size = 0 then

  begin

    formBSOD.Hide;

  end

  else

  begin

    // Move from stream into a string

    SetLength(LMsg, AData.Size);

    AData.ReadBuffer(LMsg[1], Length(LMsg));

    //

    formBSOD.ShowBSOD(Copy(LMsg, 3, MaxInt),
Copy(LMsg, 1, 1) = 'T',
Copy(LMsg, 2, 1) = 'T');

  end;

end;

Обратим внимание, что оператор if проверяет на нулевую длину. Это вполне легально посылать и принимать пустые UDP пакеты. В данном случае это используется для сигнализации серверу о снятии BSOD.

Если размер не равен 0, то данные копируются в локальную строковую перемену с помощью TStream.ReadBuffer.

UDP сервер не использует отдельного потока для каждого пакета, поскольку события OnUDPRead возникают последовательно. По умолчанию OnUDPRead возникает в главном кодовом потоке и формы и другие GUI органы управления могут использоваться безопасно.



Содержание раздела