Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Object Pascal: кроссплатформенные технологии > Консольный сервер


Автор: Lonser 27.4.2006, 20:53
Всем привет ! Подскажите пожалуйста, как реализовать idUDPServer в консольном приложении ? Вся проблема в Events -> OnUDPRead, то есть как зделать чтобы сервер в каждый момент времяни слушал порт и принимал пришедшие сообщения ; ну и выводил их на экран. Заранее благодарен. 

Автор: Snowy 27.4.2006, 21:51
Не совсем ясно в чем проблема.
Обычное динамическое создание.
Создаешь сервер, назначаешь ему событие...
Разница только в том, что событие нужно прописать ручками, а не мышой.
Это делается одинаково, что в дельфи, что в кайликсе. Для любых объектов. 

Автор: Lonser 28.4.2006, 01:03
Ну я собсно так и делаю, динамически создаю объект idUDPServer, ручками а не мышкой назначаю ему событие... но когда приходит UDP сообщение ничего не происходит... Вот посмотрите может что неправельно делаю ? Может надо OnUDPRead как-нибудь отдельным потоком запустить ?
Код

program Project1;

{$APPTYPE CONSOLE}

uses
    SysUtils,  Types,  Classes, Variants, QGraphics, QControls,
  QDialogs, QStdCtrls, IdUDPServer, IdBaseComponent,
  IdComponent, IdUDPBase, IdUDPClient, IdSocketHandle;

Type
 server = class(TidUDPServer)
 public
  Procedure UDPRead(Sender: TObject; AData: TStream;
  ABinding: TIdSocketHandle);
end;

Var
se:server;

{ server }

procedure server.UDPRead(Sender: TObject; AData: TStream;
  ABinding: TIdSocketHandle);
Var
SFS:TstringStream;
s:string;
begin
 SFS:=TStringStream.create('');
 SFS.CopyFrom(AData, AData.Size);
 Writeln(ABinding.PeerIP+' '+SFS.DataString);
 ABinding.SendTo(ABinding.PeerIP, ABinding.PeerPort, s[1], Length(s));
 SFS.Free;
end;

begin
 se:=server.Create(nil);
 se.DefaultPort:=11254;
 se.BufferSize:=8192;
 se.BroadcastEnabled:=true;
 se.Active:=true;
 se.OnUDPRead:=se.UDPRead;
readln;
 se.Free;
  { TODO -oUser -cConsole Main : Insert code here }
end.

p.s. uses`ов побольше подключил на всякий случай : потом буду убивать ненужные. 

Автор: Snowy 28.4.2006, 08:34
Цитата(Lonser @  28.4.2006,  01:03 Найти цитируемый пост)
 QGraphics, QControls,  QDialogs, QStdCtrls
Это сразу убирай, если хочешь, чтобы сервер был но-настоящему консольный. Т.е. мог работать без гуёв.

Цитата(Lonser @  28.4.2006,  01:03 Найти цитируемый пост)
 se.Active:=true;    
 se.OnUDPRead:=se.UDPRead;
Это поменяй местами. Сначала нужно присвоить все параметры, а потом активировать сервис.


Цитата(Lonser @  28.4.2006,  01:03 Найти цитируемый пост)
readln;
А вот в этом проблема.
Создай переменную, например:
Код
var ExitFlag: boolean = false;
А вместо ReadLn напиши:
Код
  repeat
    Sleep(1000); // пассивно отдыхаем 1 секунду, чтобы не создавать нагрузки
    // .... здесь можешь прописать другие действия. Например проверку состояния клавиши Esc.
  until ExitFlag;
Для выхода из программы, нужно установить ExitFlag в true. Устанавливай ее по комманде пришедшей в порт или по нажатию волшебной кнопки, ну или еще как - смотри сам. 

Автор: Lonser 28.4.2006, 12:26
Спасибо большое, только
Цитата(Snowy @  28.4.2006,  08:34 Найти цитируемый пост)
Код
  repeat
    Sleep(1000); // пассивно отдыхаем 1 секунду, чтобы не создавать нагрузки
    // .... здесь можешь прописать другие действия. Например проверку состояния клавиши Esc.
  until ExitFlag;
Для выхода из программы, нужно установить ExitFlag в true. Устанавливай ее по комманде пришедшей в порт или по нажатию волшебной кнопки, ну или еще как - смотри сам.

Закрывать по комманде пришедшей в порт : с этим проблем нет, а как отслеживать нажатие клавиши ? Помнится в pascal`е была замечательныя функция keypressed модуля CRT, может быть здесь есть какой-нибудь аналог ? 

Автор: Snowy 28.4.2006, 13:56
Честно говоря, сейчас даже не подскажу.
Кайликса под рукой нет.
Есть FreePascal, но там все просто - keypressed существует.
По идее должно быть что-то вроде
keyboard.GetKeyState()
но точно не скажу. 

Автор: Lonser 28.4.2006, 15:37
Сообщение удалено пользователем 

Автор: Snowy 28.4.2006, 15:53
Перед se.Active := true нужно добавить строчку:
Код
  se.ThreadedEvent := True;
Иначе тред соединения будет пытаться осуществить синхронизацию, а мы спим... 

Автор: Lonser 28.4.2006, 16:00
Ага, точно ! Спасибо огромное !!! 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)