Форум: "Сети";
Текущий архив: 2011.06.12;
Скачать: [xml.tar.bz2];
ВнизClientSocket + TThread = ошибка при завершении программы Найти похожие ветки
← →
Alex_C (2009-03-24 09:27) [0]В продолжении моей темы о работе телнет-сокета.
Чтоб работа телнет не тормозила работу основной программы, сокет был вынесен в отдельный тред.
собственно вот код:
constructor TTelnetThread.Create;
begin
// Создаем сокет телнета
TelnetSocket := TClientSocket.Create(nil);
TelnetSocket.OnConnecting := ClientOnConnecting;
TelnetSocket.OnConnect := ClientOnConnected;
TelnetSocket.OnDisconnect := ClientOnDisconnected;
TelnetSocket.OnRead := ClientOnRead;
TelnetSocket.OnError := ClientOnError;
inherited Create(false);
end;
destructor TTelnetThread.Destroy;
begin
TelnetSocket.Free;
inherited;
end;
procedure TTelnetThread.Execute;
begin
FreeOnTerminate := True;
try
TelnetSocket.Host := NextHost;
TelnetSocket.Port := NextPort;
TelnetSocket.Service := "telnet";
TelnetSocket.Active := True;
while TelnetSocket.Socket.Connected do
Application.ProcessMessages;
finally
TelnetSocket.Socket.Close;
end;
end;
Проблема в том, что если попытаться закрыть программу во время работы сокета велетает ошибка чтения по адресу 0000000.
Вопрос: как корректно завершить соединение с сокетом, а затем закрыть программу?
← →
Alex_C (2009-03-24 10:18) [1]В общем задача решена :)
Оказвается я перед закрытием программы делал вот что:
FormClose:
if Assigned(TelnetThread) then
begin
TelnetThread.Disconnect; // Socket.Close
TelnetThread.Free; // Тут ошибка и возникала, т.к. TelnetThread уже завершился!
end;
← →
Palladin © (2009-03-24 10:23) [2]
> while TelnetSocket.Socket.Connected do Application.
> ProcessMessages;
а вот это зачем?
← →
Palladin © (2009-03-24 10:24) [3]
> FreeOnTerminate := True;
а это какого фика в Execute делает?
← →
Palladin © (2009-03-24 10:24) [4]
> finally TelnetSocket.Socket.Close; end;
а это зачем в Execute? разве при TelnetSocket.Free он не закрывается?
← →
Palladin © (2009-03-24 10:25) [5]короче бред какой то...
← →
Slym © (2009-03-25 10:22) [6]Palladin © (24.03.09 10:25) [5]
+1000
Неблокирующий сокет в потоке :)
Alex_C (24.03.09 9:27)
сокет был вынесен в отдельный тред
ничего не вынесено... поток ничем особым и полезным не занимается
← →
Palladin © (2009-03-25 10:44) [7]... ах, он еще и неблокирующий... :)
← →
Alex_C (2009-03-25 12:46) [8]
> > while TelnetSocket.Socket.Connected do Application.
>
> > ProcessMessages;
>
> а вот это зачем?
Пока есть соединение - ожидаем ответа. А как правильно?
> > FreeOnTerminate := True;
>
> а это какого фика в Execute делает?
А почему б ему тут не стоять? Есть разница где его размещать - в Create или Execute?
> > finally TelnetSocket.Socket.Close; end;
>
> а это зачем в Execute? разве при TelnetSocket.Free он не
> закрывается?
ВЕЗДЕ написано, что закрывать сокет надо именно
TelnetSocket.Socket.Close
а не
TelnetSocket.Free
← →
Palladin © (2009-03-25 13:04) [9]
> Пока есть соединение - ожидаем ответа. А как правильно?
Какого нахрен ответа, он у тебя никаких ответов не ждет, он у тебя воздух гоняет и тормозит все приложение.
> Чтоб работа телнет не тормозила работу основной программы
С каких фигов у тебя "работа телнет" тормозит основную программу если у тебя сокет не блокирующий, чего ты бредишь? Зачем тебе отдельный поток? Воздух на самосвалах возишь?
> А почему б ему тут не стоять? Есть разница где его размещать
> - в Create или Execute?
А ты как думаешь? Execute уже в контексте созданного потока исполняется. Так наверное логичнее будет указать, что нужно разрушить объект в контексте создающего, а не создаваемого? Разве не логично?
> ВЕЗДЕ написано, что закрывать сокет надо именноTelnetSocket.
> Socket.Closeа неTelnetSocket.Free
Ну вот этого я не знаю, потому ничего не скажу. Может я и не прав.
← →
Slym © (2009-03-25 13:04) [10]Alex_C (25.03.09 12:46) [8]
Пока есть соединение - ожидаем ответа. А как правильно?
правильно использовать боп поток при блокирующем режиме сокета (ClientType = ctBlocking)
а у тебя ctNonBlocking
при ctBlocking не используются события типа:
TelnetSocket.OnConnecting
TelnetSocket.OnConnect
TelnetSocket.OnDisconnect
TelnetSocket.OnRead
TelnetSocket.OnError
пример работы в блокирующем режиме рассмотрен тут http://delphimaster.net/view/6-1227604925/
← →
Сергей М. © (2009-03-25 13:12) [11]
> Alex_C (25.03.09 12:46) [8]
>
>
Обращение к VCL-объектам в доп.потоке небезопасно, а в большинсве случаев и недопустимо.
← →
Alex_C (2009-03-25 14:18) [12]Ок! Спасибо!
С сокетами вообще мало дело имел, а в тредах вообще.
Разобрался!
правильно для бликирующего сокета будет так:
DataLength := TelnetSocket.Socket.ReceiveLength;
Buf := GetMemory(DataLength);
while TelnetSocket.Socket.Connected do
begin
Size := TelnetSocket.Socket.ReceiveBuf(Buf, DataLength);
if Size <= 0 then
Continue;
ReadDataFromTelnet(Buf, Size);
end;
где ReadDataFromTelnet - альнейшая обработка полученных данных.
Я правильно понимаю?
← →
Alex_C (2009-03-25 14:35) [13]Поторопился.
Вот так правильно:
while TelnetSocket.Socket.Connected do
begin
DataLength := TelnetSocket.Socket.ReceiveLength;
if DataLength <= 0 then
Continue;
SetLength(Buf, DataLength);
TelnetSocket.Socket.ReceiveBuf(Buf[0], DataLength);
ReadDataFromTelnet(Buf, DataLength);
end;
← →
Сергей М. © (2009-03-25 14:46) [14]
> правильно понимаю?
Не совсем.
1. Вызов ReceiveLength в блокирущем режиме не обязателен - логика его использования более уместна в неблок.режиме с асинхронными нотификациями (ClientType = ctNonBlocking)
2. Результат вызова ReceiveBuf следует интерпретировать след.образом:
< 0 - возникла неустранимая ошибка, связанная с невозможностью дальнейшей работы с данным соединением, например, кот Васька только что перегрыз пачкорд.Continue
лишен смысла, следует закругляться.
= 0 - удаленный партнер по соединению корректно разорвал соединение по своей инициативе.Continue
тут также лишен смысла, следует закругляться.
> 0 - из вх.очереди актуально выбрано Size байт, можно их обрабатывать, при этом соединение на этот моменьт может уже и не существовать, будучи разорванным по тем или иным причинам.
← →
Alex_C (2009-03-25 16:28) [15]
> Не совсем.
Ок! Понял - буду разбираться дальше!
Страницы: 1 вся ветка
Форум: "Сети";
Текущий архив: 2011.06.12;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.004 c