-
День добрый. Ранее с TCP/IP не сталкивался, поэтому возможно вопрос будет смешным....
Создаю две програмки, в одной TIdTCPServer в другой TIdTCPClient. Настраиваю хост,порт. Запускаю. на сервере стартую IdTCPServer.Active:=true;
на серваке определил обработчики:
procedure TfrmMain.IdTCPServerConnect(AThread: TIdPeerThread);
begin
Memo1.Lines.Add(FormatDateTime('hh:nn:ss.zzz',now)+' - Соединение');
end;
procedure TfrmMain.IdTCPServerExecute(AThread: TIdPeerThread);
begin
if not AThread.Terminated and AThread.Connection.Connected then
begin Memo1.Lines.Add(FormatDateTime('hh:nn:ss.zzz',now)+' - Выполнение'); sleep(1000); end;
end;
procedure TfrmMain.IdTCPServerDisconnect(AThread: TIdPeerThread);
begin
if AThread.Terminated Or Not AThread.Connection.Connected then
Memo1.Lines.Add(FormatDateTime('hh:nn:ss.zzz',now)+' - Отсоединение');
end;
При коннекте на клиенте, на сервере срабатывает первый обработчик и начинает выполнение второй.
При попытке Disconnect на клиенте, на сервере ничего не происходит и "Выполнение" попрежнему происходит и третий обработчик тоже не запускается.
В чем прикол?
-
так как второй обработчик ничего не делает, он бес понятия о текущем состоянии соединения. поэтому
второе:
из вторичных потоков нельзя работать с мемами и другими элементами gui
-
на счет вторичных потоков и vcl я знаю, просто временно для пробы сделал.
а что значит ничего не делает... что нужно делать, чтобы он знал состояние AThread.Connection.Connected?
-
ну для начала хотя бы читать то, что ему клиент шлет.
-
а я пока ничего не слал, только подключился и отключаюсь.... ну сейчас попробую прочитать...
-
и еще поправка.
OnDisconnect генерируется только если сам сервер вызвал DoDisconnect или то, что вызывает DoDisconnect
разрыв соединения по инициативе клиента не приводит к этому событию
-
а я пока ничего не слал, только подключился и отключаюсь.... ну сейчас попробую прочитать...
сервер ничего не делает.
ни пишет и не читает.
в таком случае не по барабану ли ему, подключен к нему клиент или не подключен?
сервер же нифига не делает.
-
вроде получилось.. спасибо. ну это наверняка у меня не последний вопрос был :-)))
-
Теперь пытають клиентом отправить текст сообщ с пом. Writeln(msg)
а вот на сервере не могу его принять
procedure TfrmMain.IdTCPServerExecute(AThread: TIdPeerThread);
var s:string;
begin
if not AThread.Terminated and AThread.Connection.Connected then begin
s:=AThread.Connection.ReadLn;
if s<>'' then begin
TextToLog:=s;
AThread.Synchronize(frmMain.PrintToLog);
end;
end;
end;
будто зависает на строке s:=AThread.Connection.ReadLn;
(смотрел в трейсе)
-
ждет ограничителя строки видимо
-
а какой должен быть ограничитель? Я посылаю данные с помощью WriteLn, я так понимаю, что там ограничитель присутствует...
кстате попробовал еще считать с помощью s:=AThread.Connection.ReadLn(lf,10); все равно ожидает неограниченное время, те тймайт не срабатывает... Что неправильно написал?
-
> zsv (17.12.2009 06:42:10) [10]
Для строк стандартный разделитель CRLF
-
будто зависает на строке s:=AThread.Connection.ReadLn;
так он же у тебя зациклен.
-
как зациклен? я ставлю брекпоинт, выполняю s:=AThread.Connection.ReadLn;
и все, до след. команды не доходит...
> Для строк стандартный разделитель CRLF
а WriteLn этот разделитель не вставляет?
-
> zsv © (17.12.09 12:31) [13]
Не помню как в 9-ке, а в 10-ке WriteLn по дифолту дополняет отправляемую строку терминатором EOL (константа определена как CR + LF), а ReadLn без параметров ожидает строку с терминатором LF
-
> zsv © (17.12.09 12:31) [13]
>
> как зациклен?
Он имел ввиду что обработчик OnExecute вызывается в цикле, условием штатного выхода из которого по умолчанию является Connected = False
-
>Не помню как в 9-ке, а в 10-ке WriteLn по дифолту дополняет отправляемую строку терминатором EOL (константа определена как CR + LF), а ReadLn без параметров ожидает строку с терминатором LF.
Да, дело было в этом...
так s:=AThread.Connection.ReadLn(EOL); все заработало