Авторские статьи Пример использования компонента Indy UDP Server

Discussion in 'Статьи' started by SC40, 15 May 2015.

  1. SC40

    SC40 New Member

    Joined:
    8 May 2015
    Messages:
    6
    Likes Received:
    2
    Reputations:
    3

    Пример использования компонента Indy UDP Server

    Статья рассчитана для начинающих Delphi программистов и содержит базовую информацию о применении компонента idUDPServer в своем приложении.
    Предполагается, что рабочая среда пользователя - Delphi 7й версии с установленными по умолчанию компонентами Indy.

    Компонент idUDPServer предназначен для работы с сетевым протоколом UDP. Может быть использован как в роли клиента так и сервера. Существует и компонент idUDPClient, являющийся, по сути подобием idUDPServer с урезанным функционалом, что означает рациональность употребления idUDPServer в любых случаях.

    Для начала, после запуска Delphi в режиме создания нового форменного приложения ищем на палитре Indy Servers компонент idUDPServer и размещаем его в любом месте формы, как любой иной невизуальный компонент.

    [​IMG]

    Хотя, реально и совершенно бесформное включение компонента.

    У компонента имеется 2 основные процедуры, которые и обеспечивают его работу по вводу-выводу работы с UDP. Это Send(AHost: string; const APort: Integer; const AData: string) и IdUDPServer1UDPRead(Sender: TObject; AData: TStream; ABinding: TIdSocketHandle).

    Процедура Send, как можно догадаться по названию, отправляет наши данные (AData) по указанным в ней адресу (AHost), порту (APort). Более для отправки ничего настраивать не требуется.

    Пример отправки данных из Edit:
    Code:
    procedure TForm1.Button2Click(Sender: TObject);
    begin
    memo1.Clear; //чистим форму в которую потом поступят данные
    idUDPServer1.Send(Edit1.Text,StrToInt(Edit2.Text),Edit3.Text); //отправляем запрос "яяяяgetservers 68 empty full" из тестового поля
    end;
    Для приема данных нужно в свойствах компонента визуально или в коде выполнить настройки: указать свойство Active = true, Bindings - IP и порт для прослушивания.
    Если наш сервер активен, то при поступлении на указанный IP и порт пакета UDP будет выполнена процедура/событие IdUDPServer1UDPRead, в поток AData которой будет помещено содержимое пакета. Прочитать данные из потока в строковую переменную text поможет следующий код:
    Code:
     MemStream:= TMemoryStream.Create;
    MemStream.LoadFromStream(AData);
    MemStream.Position:=0;
    SetString(text, nil, MemStream.Size);
    MemStream.Read(Pointer(text)^, MemStream.Size);
    MemStream.free;
    Ну а с текстовой строкой мы можем выполнять уже любые действия по парсингу содержимого. И при нужде можно читать не в тип string, а в array of char.

    Пример приема данных с игрового сервера (мастер-сервера) с последующим парсингом и выводом (принимается список IP адресов в HEX формате):
    Code:
    procedure TForm1.IdUDPServer1UDPRead(Sender: TObject; AData: TStream;
    ABinding: TIdSocketHandle);
    var text,iptext:string; MemStream: TMemoryStream; n,ofs:cardinal;
    begin
    text:='';
    try
    MemStream:= TMemoryStream.Create;
    MemStream.LoadFromStream(AData);
    MemStream.Position:=0;
    SetString(text, nil, MemStream.Size); //читаем содержимое в строку
    MemStream.Read(Pointer(text)^, MemStream.Size);
    MemStream.free;
    except end;
    iptext:='';
    ofs:=7;
    text:=StringReplace(text,'\EOT','\',[rfReplaceAll , rfIgnoreCase]); //мы знаем, что должно поступить и начинаем разбор, здесь - замена
    for n:=1 to length(text) do //ищем фрагменты с IP в HEXе
    begin
    case ofs of
    1..3 : iptext:=iptext+IntToStr(cardinal(text[n]))+'.';
    4 : iptext:=iptext+IntToStr(cardinal(text[n]))+':';
    6 : iptext:=iptext+IntToStr(StrToInt('$'+IntToHex(cardinal(text[n-1]),2)+IntToHex(cardinal(text[n]),2)))+#13+#10; //выбираем сам IP-шник
    end;
    if ((text[n]='\') and (ofs=7)) then ofs:=1 else if ofs<7 then ofs:=ofs+1;
    end;
    memo1.Lines.Add(iptext); //добавляем распарсенный IP в Memo
    end;
    Как выглядит наше UDP приложение:

    [​IMG]

    Программный пример, использованный в статье можно загрузить здесь (220 KB).