Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Сети > Элементраное в Indy


Автор: elestrago 16.5.2008, 13:55
Парни покажите пожалуйста как элементарно отправить\приянять текст используя INDY tcp server\client 

желаетльно бы увидить какой нибуть работающий исходник(клиент отправляет текст серверу сервер выводит в мемо и наоборот)!! а то я не фига не могу понять в инди, до этого работал в TClient\serverSocket там это делается элементарно!!

и что еще за событие Onexecute в сервере инди?   smile 

Пс читал Глубины инди но там я не фига не понял есть ли что нибуть наподобии только не глубины а "поверхность" инди ?  smile 

Автор: elestrago 16.5.2008, 14:54
блин сори за тему, просто я криво поставил инди 10 и все коды которые я пробовал не работали... теперь 9ю вернул и все заработало и я все понял ))))

Автор: DmitryHT 16.5.2008, 20:57
поставь 10.2.3 из snapshot - вообще сказка  smile 

Автор: Beltar 18.5.2008, 13:41
Неожиданно вперся в необходимость работать с сетью. Нужно написать сервер, который бы отслеживал состояние множества клиентов. Выбрал Indy 9, могу изменить на Indy 10, но там я не нашел компонента TIdThreadMgrDefault с которым дается пример в DRKB. ХЗ, что там еще поменялось.

Положил на форму TidTCPServer, TidTCPClient, для реализации множества потоков, как я понял, нужен TIdThreadMgrPool вместо TIdThreadMgrDefault.

Задал для сервера DefaultPort=5500, он вроде ничей. Сразу вопрос, как это свойство связано со свойством Bindings?

Указал у клиента хост и порт. Чем отличаются Bound Port и Port?

Пробую вызвать TCPClient.Connect(5); и получаю эксепшен, что "address and port already in use". Что делать?

Автор: Beltar 19.5.2008, 12:10
Так, похоже, в одну софтину клиент и сервер не положишь. Года 2,5 назад я с Winsock API ковырялся так вроде получалось.

Остается вопрос, что нужно использовать, чтобы обрабатывать подключения с множества компов: TIdSchedulerOfThreadPool или что иное (ничего).

Автор: dumb 19.5.2008, 15:06
Цитата(Beltar @  19.5.2008,  13:10 Найти цитируемый пост)
Так, похоже, в одну софтину клиент и сервер не положишь.
"ложил" - все работало. только одно "но" - передаваемая инфа должна влезать в размер буфера передачи. иначе кофликты где-то в индейских дебрях происходят.

Цитата(Beltar @  18.5.2008,  14:41 Найти цитируемый пост)
для реализации множества потоков, как я понял, нужен TIdThreadMgrPool
нет. оно безо всяких "добавок" много-поточное. причем именно пул. этим компонентом ты просто даешь себе возможность управлять этим пулом, что в общем случае нафик не нужно.

Цитата(Beltar @  18.5.2008,  14:41 Найти цитируемый пост)
Задал для сервера DefaultPort=5500, он вроде ничей. Сразу вопрос, как это свойство связано со свойством Bindings?
в свойстве Bindings(string list) ты перечисляешь все интерфейсы, на которых хочешь "слушать". в строке биндинга можно писать либо просто адрес интерфейса, либо пару адрес:порт. вот если указан только адрес, к нему приклеивается DefaultPort.

Цитата(Beltar @  18.5.2008,  14:41 Найти цитируемый пост)
Указал у клиента хост и порт. Чем отличаются Bound Port и Port?
Bound - это твой исходящий порт(который как правило не представляет интереса).

Цитата(Beltar @  18.5.2008,  14:41 Найти цитируемый пост)
Что делать?
демонстрировать код.

Автор: Beltar 25.5.2008, 19:28
Еще вопрос, что делать с Connection Closed Gracefully? Просто пингую по таймеру Timer1 сервер. При посылке запускаю Timer2, который проверяет таймаут. Если что-то принято, то таймер1 перезапускается, таймер2 останавливается. При срабатывании Timer2 считаею, что связь порвалась и запускаю Timer4, в котором попробую соединиться.


Код

procedure TForm2.Timer1Timer(Sender: TObject);
begin
CL.Socket.WriteLn('CMD:Ping');
Timer1.Enabled:=false;
Timer2.Enabled:=true;
end;

procedure TForm2.Timer2Timer(Sender: TObject);
begin
Timer1.Enabled:=false;
Timer2.Enabled:=false;
MMLog.Lines.Add(TimeToStr(Now)+' Нет ответа от сервера');
CL.Disconnect;
Timer4.Enabled:=true;

procedure TForm2.Timer3Timer(Sender: TObject);
var L:Integer;
    S:String;
begin
if not CL.Connected then Exit;
S:=CL.IOHandler.ReadLn;
L:=Length(S);
if L>0 then
  begin
  MMLog.Lines.Add(S);
  Timer1.Enabled:=false;
  Timer1.Enabled:=true;
  Timer2.Enabled:=false;
  end;

end;

procedure TForm2.Timer4Timer(Sender: TObject);
begin
if Connect then
  begin
  Timer4.Enabled:=false;
  MMLog.Lines.Add(TimeToStr(Now)+' Восстановлено соединение с сервером');
  end
  else ErrorHandle;
end;


Все нормально пока сервер не закрываю, после этого начинает добивать ошибка Connection Closed Gracefully и события таймеров не срабатывают. Где ловить это исключение мне непонятно. При перезапуске сервера связь не всстанавливается.

Автор: dumb 26.5.2008, 04:18
Цитата(Beltar @  25.5.2008,  20:28 Найти цитируемый пост)
Где ловить это исключение мне непонятно.
везде, где вызываешь индейские функции соединения/посылки/приема.

Автор: MetalFan 26.5.2008, 08:07
Beltar, имхо не самая лучшая мысль использовать TTimer...

Цитата(Beltar @  25.5.2008,  19:28 Найти цитируемый пост)
после этого начинает добивать ошибка Connection Closed Gracefully

это вроде как значит, что с "другой стороны" закрыли соединение...

Цитата(Beltar @  25.5.2008,  19:28 Найти цитируемый пост)
Просто пингую по таймеру Timer1 сервер. 

Цитата(Beltar @  25.5.2008,  19:28 Найти цитируемый пост)
CL.Socket.WriteLn('CMD:Ping');

эээ... это разве пинг?

Автор: Beltar 27.5.2008, 07:27
Цитата

эээ... это разве пинг?


А какая разница, что послать? Ну допустим у меня простейший текстовый протокол. Приставил к строке CMD: считаю, что это команда, нет, просто сообщение.

Цитата

это вроде как значит, что с "другой стороны" закрыли соединение...


Ну да. Достаточно закрыть сервер, как возникает такое исключение. И дальше каждые несколько секунд. Мне не понятна такая логика, если клиент сам обнаруживает разрыв связи (=> я изобретаю велосипед), то почему он просто не переходит в дисконнектид?

Автор: MetalFan 27.5.2008, 10:33
Цитата(Beltar @  27.5.2008,  07:27 Найти цитируемый пост)
А какая разница, что послать?

надо называть все своими именами. ping - это ping. а то, что ты там сам шлешь - ни разу не пинг.


Цитата(Beltar @  27.5.2008,  07:27 Найти цитируемый пост)
И дальше каждые несколько секунд.

прямо таки?
и в каком месте возникает?

Автор: Beltar 28.5.2008, 15:21
Понятие "сам" очень относительно. smile Впрочем, как посоветовали выше я затраил все, что можно:

Код

procedure TForm2.Timer1Timer(Sender: TObject);
begin
try
CL.Socket.WriteLn('CMD:Ping');
except
CL.Disconnect;
MMLog.Lines.Add('Ошибка при работе с сервером. Связь разорвана');
Timer4.Enabled:=true;
end;
Timer1.Enabled:=false;
end;

procedure TForm2.Timer3Timer(Sender: TObject);
var L:Integer;
    S:String;
begin
if not CL.Connected then Exit;
try
L:=CL.IOHandler.InputBuffer.Size;
if L>0 then
  begin
  S:=CL.IOHandler.Readln;
  MMLog.Lines.Add(S);
  Timer1.Enabled:=false;
  Timer1.Enabled:=true;
  Timer2.Enabled:=false;
  end;
except
CL.Disconnect;
MMLog.Lines.Add('Ошибка при работе с сервером. Связь разорвана');
Timer4.Enabled:=true;
end;

end;

procedure TForm2.Timer4Timer(Sender: TObject);
begin
if Connect then//там тоже try внутри
  begin
  Timer4.Enabled:=false;
  MMLog.Lines.Add(TimeToStr(Now)+' Восстановлено соединение с сервером');
  end
end;



Так все нормально. Спасибо за помощь. smile

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