Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Как получить сообщение от TCPServera? [D7, WinXP]


Страницы:   1 2

Anton. ©   (2004-06-09 16:06:00) 

Проблема такая отправляю сообщение на сервер
procedure TForm1.BitBtn1Click(Sender: TObject);
begin
 IdTCPClient1.WriteLn(‘М'+Memo2.Text);
end;
на сервере обработчик
 if Msg[1]='M' then
  begin
   BroadcastMessage('E', 'New Message');
  End;
Как клиенту получить это сообщение, делать ReadLn по таймеру?


Петров   (2004-06-22 17:53:00) [1]

Да, признаю свою ошибку.


alienserg   (2004-06-18 02:40:00) [2]

Петров   (15.06.04 13:31) [31]

буферы для ReadLn и WriteLn разные.
FInputBuffer: TIdManagedBuffer;
FWriteBuffer: TIdSimpleBuffer;


Петров   (2004-06-15 13:31:00) [3]

Когда TIdTcpClient делает ReadLn, он обращается к внутреннему буферу Indy. Поэтому, читая без задержки (не дожидаясь отправки серверу), легко можно считать свое же сообщение, посланное серверу тем же самым клиентом перед этим через TIdTcpClient.WriteLn!


колька   (2004-06-14 04:37:00) [4]

if client1.LastCmdResult.Text.Text = 'ok' then
поменять на
if client1.readln = 'ok' then


колька   (2004-06-14 03:54:00) [5]

В else кидай
asender.Thread.Connection.WriteLn('no');
в клеенте  обработчик:
case if client1.LastCmdResult.Text.Text of
'ok':readin(buf);
'no':exit;


колька   (2004-06-14 03:47:00) [6]

alienserg  (14.06.04 02:44) [27]
>Это сообщение попадает в пункт назначения и сидит в TCP стеке и
>ждет, когда тамошний клент его опросит, выполнив ReadLn
>например.

Клиенту всеже придется опросить сервер.
Тогда можно сделать вот так:
клиент (по таймеру) опрашивает сервер на предмет появления для него(клиента) нового сообщения.
client1.SendCmd( 'numb');
if client1.LastCmdResult.Text.Text = 'ok' then
readin(buf);
Сервер.
var
mess: boolean;
procedure TForm1.Server1Command1 numb(ASender: TIdCommand);
begin
if mass = true then begin
asender.Thread.Connection.WriteLn(ok);
asender.Thread.Connection.WriteLn('нужная строка);
end else begin
exit;
end;


alienserg   (2004-06-14 02:44:00) [7]

колька   (12.06.04 23:44) [26]

сервер может послать сообщение клиенту например по приходу сообщения от другого клиента. Это сообщение попадает в пункт назначения и сидит в TCP стеке и ждет, когда тамошний клент его опросит, выполнив ReadLn например.
Когда TIdTcpClient делает ReadLn, он обращается именно к локальному TCP стеку, а не к серверу.
Во всех примерах, поставляемых с Indy, стандартный прием работы с TIdTcpClient - опрос по таймеру(ReadLn, ReadInteger и т.д.). Например раз в 200 миллисекунд.
Обязательно ставьте на форму TIdAntifreeze, одно на приложение, иначе форма будет "замораживаться", поскольку Indy сокеты работают в блокирующем режиме.
Если вы используете TIdTcpServer и что-то хотите отрисовать на формах по событию OnExecute, то обязательно делайте Synchronize() или используйте для этого дела TIdSync.
Тот же самый принцип и для работы с базой данных. Создавайте/уничтожайте экземпляр датамодуля при каждом запросе или используйте единственный датамодуль, проставляя критические секции или создавайте пул датамодулей и регулируйте их выдачу тредам семафорами. Точнее не датамодулей а наборов dbconnection+dbqueries.


колька   (2004-06-12 23:44:00) [8]

Может я не доганяю, но клиент на то и клиент что б спращивать.
ИМХО сервер никак не сможет произвольно послать клиенту дату. Просто клиент не опрашивает порт, лишь на время timeout`а, ожидая ответ сервера. Можно конечно и порт слушать и коннект ловить, но это помоему уже будет сервер, а не клиент.


Digitman   (2004-06-11 08:18:00) [9]


> Verg ©   (10.06.04 18:14) [23]


> где народ берет этот шаблон Execute


ну где ж ? разумеется, здесь же , в статьях...

некто Карих Николай в свое время подсуетился неудачно ...
хотя ... обвинять его во всех смертных грехах тоже вроде бы нет повода - там ведь в статье как раз слово "шаблон" явно фигурирует ...


Антон.   (2004-06-10 18:29:00) [10]

Спасибо ошибки понял, учту


Verg   (2004-06-10 18:14:00) [11]


> [21] Anton.   (10.06.04 17:56)
> что то вроде получилось, ваши оценки?
>
> procedure TForm1.FormCreate(Sender: TObject);
> var
>  MyThread: TThread;
> begin
>  Memo2.Clear;
>  IdTCPClient1.Connect;
>  T1 := TMyThread1.Create(False);
> end;
>
> procedure TForm1.FormClose(Sender: TObject; var Action:
> TCloseAction);
> begin
>  IdTCPClient1.Disconnect;
> end;
>
> procedure TForm1.BitBtn2Click(Sender: TObject);
> begin
>  close;
> end;
>

> procedure TForm1.BitBtn1Click(Sender: TObject);
> begin
>  IdTCPClient1.WriteLn('M'+Memo1.Text);
> end;
>
> procedure TMyThread1.Execute;
> begin
>  while not Terminated do
   begin
      NewS := IdTCPClient1.ReadLn;
      if NewS <> '' then
        Synchronize(Show_NewS);
   end;
> end;
>
> procedure TMyThread1.Show_NewS;
> begin
     Memo1.Lines.Add(NewS);
> end;


NewS : string; - поле TMyThread1

P.S. А где народ берет этот шаблон Execute: while not Terminated do Synchronize(DoWork) ?
P.P.S. Эта "рыба" плохо пахнет...


Digitman   (2004-06-10 18:02:00) [12]


> ваши оценки?


твердый кол

за абсолютно бездумное сдирание кода метода
TMyThread1.Execute;


Anton.   (2004-06-10 17:56:00) [13]

что то вроде получилось, ваши оценки?

procedure TForm1.FormCreate(Sender: TObject);
var
 MyThread: TThread;
begin
 IdTCPClient1.Connect;
 T1 := TMyThread1.Create(False);
 T1.Priority := tpLowest;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
 IdTCPClient1.Disconnect;
end;

procedure TForm1.BitBtn2Click(Sender: TObject);
begin
 close;
end;

procedure TForm1.ListenServer;
begin
 Memo1.Text:=IdTCPClient1.ReadLn;
end;

procedure TForm1.BitBtn1Click(Sender: TObject);
begin
 IdTCPClient1.WriteLn('M'+Memo2.Text);
 Memo2.Clear;
 ListenServer;
end;

procedure TMyThread1.Execute;
begin
 while not Terminated do
  Synchronize(DoWork);
end;

procedure TMyThread1.DoWork;
begin
 Form1.ListenServer;
end;


Verg   (2004-06-10 11:56:00) [14]


> Anton.   (10.06.04 11:47) [19]
> В примерах DELPHI есть программка NETCHAT вот там на форме
> лежит как клиентский компонент так и серверный


Ну и что?

> Anton.   (10.06.04 11:38) [17]
> Когда и в какой момент второму клиенту надо вызывать IdTCPClient1.ReadLn,
> опрашивать сервер через промежутки времени?


Да не сервер опрашивать! А свой сокет, подключенный к серверу.
Хоть через промежутки времени, хоть в отдельном потоке, хоть сразу же и readln делай, а на форму кинь antifreez... Дело вкуса и соответствия задаче.
Но, IdTCPClient не имеет возможности асинхронно, самостоятельно сообщить, что в его сокете появились какие-то принятые данные.


Anton.   (2004-06-10 11:47:00) [15]

В примерах DELPHI есть программка NETCHAT вот там на форме лежит как клиентский компонент так и серверный


Digitman   (2004-06-10 11:47:00) [16]


> Когда и в какой момент второму клиенту надо вызывать IdTCPClient1.ReadLn


в тот момент, когда этот клиент желает получить  потенциально отправляемое сервером строковое сообщение


> опрашивать сервер через промежутки времени?


это еще зачем ? ты расчитываешь что-то получить от сервера ? ну так и вызывай ReadLn() ! Как только сервер сподобится тебе что-то послать, ф-ция возвратит управление и вернет результирующу полученную от сервера строку


Anton.   (2004-06-10 11:38:00) [17]

Когда и в какой момент второму клиенту надо вызывать IdTCPClient1.ReadLn, опрашивать сервер через промежутки времени?


Digitman   (2004-06-10 11:23:00) [18]


> получил сразу же отклик


правильно, получил ..
потому что IdTCPClient1.ReadLn выполнил

а тот (другой) клиент, который в этот момент "бил баклуши", не вызывая IdTCPClient1.ReadLn, разумеется, ничего не получил .. а с какого перепугу он что-то получить должен был. если даже пальцем не пошевелил ? законнектился и сидит себе ждет у моря погоды ?

"спрашивающий да получит ответ"(с)


Anton.   (2004-06-10 11:16:00) [19]

дальше запустил два клиента, один набрал сообщение и нажал кнопку
procedure TForm1.BitBtn1Click(Sender: TObject);
var Response : string;
begin
IdTCPClient1.WriteLn(Memo2.Text);
Response:=IdTCPClient1.ReadLn;
end;
получил сразу же отклик, второй сидит ничего не получив. Или получил да я не смог обработать  прием?


Digitman   (2004-06-10 11:05:00) [20]

procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread);
var
i: Integer;
Msg : string;
begin
Msg    := AThread.Connection.ReadLn;
with AThread.Connection.Server.Threads.LockList do
try
 for i := 0 to Count -1 do
  try
   TIdPeerThread(Items[i]).Connection.WriteLn(Msg);
  except
  end;
finally
  IdTCPServer1.Threads.UnLockList;
end;
end;


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо