Форум: "Сети";
Текущий архив: 2005.03.06;
Скачать: [xml.tar.bz2];
ВнизОбработка ошибки 10061, TClientSocket Найти похожие ветки
← →
Delpher_Gray (2004-12-30 07:37) [0]Добрый день, Мастера !
Пишу многопотоковую программу, использующую TClientSocket. В клиент-сокете на событие ошибки - OnError, чтоб не вылазило ошибок я написал "ErrorCode := 0;". Но всё-же тут иногда возникает ошибка 10061 ! С чём она связана и как её обработать чтоб подобного не повторялось ?
Программа вообще должна работать автоматически, а тут эта ошибки иногда выскакивает... Если Ок не нажать все потоки стают...
Заранее благодарен.
← →
Digitman © (2004-12-30 08:14) [1]http://delphimaster.net/view/6-1104233111/
← →
Delpher_Gray (2004-12-30 08:47) [2]Я ведь сразу сказал что в OnError строка "ErrorCode := 0;" у меня есть.
Тут ошибка возникает ещё до события OnError. По-моему сразу после открытия сокета. Например когда у меня инет отключён, а я пытаюсь подрубиться вот тогда - 10061. Пробывал впихнуть Sock.Open в try...except, всё-равно вылазит...procedure TMyThread.Execute;
begin
Sock := TClientSocket.Create(nil);
// тут настраиваю порт и хост, проверяю юзатется ли прокси
Sock.ClientType := ctNonBlocking;
Sock.OnConnect := SockConnect;
Sock.OnDisconnect := SockDisconnect;
Sock.OnError := SockError;
Sock.OnRead := SockRead;
Synchronize(Sock.Open);
end;
Вот...
← →
Digitman © (2004-12-30 10:58) [3]procedure TMyThread.Execute;
var
Msg: TMsg;
begin
try
//создаем гнездо
Sock := TClientSocket.Create(nil); //по дифолту режим уже ctNonBlocking, явно устанавливать его не нужно
try
// тут настраивай св-ва Host, Port и т.д.
Sock.OnConnect := SockConnect;
Sock.OnDisconnect := SockDisconnect;
Sock.OnError := SockError;
Sock.OnRead := SockRead;
Sock.Open; //стартуем асинхронную операцию коннекта
//*****************************************************
//** цикл ожидания/выборки/диспетчеризации сообщений **
//*****************************************************
//пока трэду не было команды закругляться по хозяйству
//ожидаем сообщения в очереди сообщений текущего трэда
while not Terminated and GetMessage(Msg, 0, 0, 0) do
if Msg.hWnd = 0 then
//здесь диспетчеризуем сообщения, адресованные непосредственно трэду, если они имеются
Dispatch(Msg.Message)
else
//а здесь диспетчеризуем сообщения, адресованные окнам, созданным текущим трэдом, в т.ч. и в 1-ю очередь - окну, созданному классом TClientWinSocket для приема нотиф.сообщений гнезда о происходящих транспортных событиях и ошибках
DispatchMessage(Msg);
finally
//бузусловно уничтожаем гнездо
Sock.Free;
end;
except
//здесь, если нужно, протоколируем все возникшие в ходе работы трэда незапланированные искл-я
//и ни в коем случае не плодим новые !!! иначе - кирдык
end;
end;
procedure TMyThread.Destroy;
begin
if GetCurrentThreadId <> ThreadId then
PostThreadMessage(ThreadId, WM_QUIT, 0, 0);
inherited;
end;
Вот...
← →
Digitman © (2004-12-30 11:08) [4]главная твоя ошибка - в непонимании того что в ходе исполнения Open() создается невидимое окно, которое будет "принадлежать" трэду, вызвавшему этот метод .. в твоем случае (см.Synchronize) это будет основной трэд (зачем, спрашивается ?), он же как "владелец" созданного окна и обязан после этого принимать и диспетчеризовать оконные сообщения, посылаемые гнездом .. НО ! .. запустив асинхр.операцию коннекта ты тут же завершаешь работу трэда и, вероятно, следом уничтожаешь объект MyThread, что вообще недопустимо, ибо ты назначит методы этого объекта в кач-ве обработчиков событий гнезда
← →
Delpher_Gray (2004-12-30 12:11) [5]а вот теперь код проги приведу:
procedure TMyThread.Execute;
var
Msg: TMsg;
begin
try
Sock := TClientSocket.Create(nil);
try
//хост и порт
Sock.OnConnect := SockConnect;
Sock.OnDisconnect := SockDisconnect;
Sock.OnError := SockError;
Sock.OnRead := SockRead;
Sock.Open;
while not Terminated and GetMessage(Msg, 0, 0, 0) do
if Msg.hWnd = 0 then
Dispatch(Msg.Message)
else
DispatchMessage(Msg);
finally
Sock.Free;
end;
except
NextOpp;
end;
end;
destructor TMyThread.Destroy;
begin
if GetCurrentThreadId <> ThreadId then
PostThreadMessage(ThreadId, WM_QUIT, 0, 0);
inherited;
end;
procedure TMyThread.SockConnect(Sender: TObject; Socket: TCustomWinSocket);
begin
// тут шлю HTTP заголовки
end;
// тут читаю данные с гнезда. Это ведь HTTP, читаю до отключения.... Header и Content - это TStringList"ы.
procedure TMyThread.SockRead(Sender: TObject; Socket: TCustomWinSocket);
var
EndPos: integer;
begin
if HeaderReceive then
begin
Header.Text := Header.Text+Socket.ReceiveText;
EndPos := Pos(#13#10#13#10, Header.Text);
if EndPos > 0 then
begin
Content := TStringList.Create;
Content.Text := Copy(Header.Text, EndPos+4,
Length(Header.Text)-EndPos-4);
Header.Text := Copy(Header.Text, 1, EndPos);
HeaderReceive := false;
end;
end else
Content.Text := Content.Text+Socket.ReceiveText;
end;
procedure TMyThread.SockDisconnect(Sender: TObject; Socket: TCustomWinSocket);
begin
// выполняю действия с полученными данными
NextOpp; // След. операция
end;
procedure TMyThread.SockError(Sender: TObject; Socket: TCustomWinSocket;
ErrorEvent: TErrorEvent; var ErrorCode: Integer);
begin
ErrorCode := 0;
NextOpp;
end;
procedure TMyThread.NextOpp;
begin
// вот тут выполняется следующая операция.
Sock.Close;
// настраивается порт и хост и заного
Sock.Open;
end;
Всё ли верно ? А систему мне нада подучить срочно :( Чтож, займусь...
← →
Delpher_Gray (2004-12-30 12:15) [6]а вот ошибка у меня...
try
Sock := TClientSocket.Create(nil);
...
except
// NextOpp; // !!!
// тут ведь нужно или ничего не делать чтоб поток сам уничтожился, или поменять хост и порт и попробывать снова так ведь ?
end;
← →
Digitman © (2004-12-30 12:44) [7]
> Всё ли верно ?
нет.
далеко не все.
начнем с главного - в случае неблок.режима при возникновении ошибки, связанной с недоступностью хоста, не будет никаких исключений, а будет вызван твой обработчик SockError.. вот в нем- то , очевидно, и следует рестартовать механизм повторного коннекта с измененными параметрами
> Delpher_Gray (30.12.04 12:15) [6]
именно в данной ситуации единственное что может привести к исключению - это отказ при конструировании объекта-гнезда .. это - серьезный (критический) отказ, и он м.б. связан с чем угодно, но только не с механизмом коннекта, поэтому бессмысленно в обработчике искл-я пытаться выполнять реконнект - объект-то не создан !
← →
Delpher_Gray (2004-12-30 12:55) [8]
> будет вызван твой обработчик SockError.. вот в нем- то ,
> очевидно, и следует рестартовать механизм повторного коннекта
> с измененными параметрами
Ну вот там как раз и выполняется NextOpp;
> поэтому бессмысленно в обработчике искл-я пытаться выполнять
> реконнект - объект-то не создан
Так... В даннй ситуации возможен ли такой вариант что первый раз сокет не создавля, а при второй попытке создался ??
В моей программер нужно сделать N"е кол-во операций. Что мне делать в этой ситуации ? Тормознуть все потоки или попробывать ещё раз (выполнить Execute) ?
← →
Digitman © (2004-12-30 13:06) [9]
> В даннй ситуации возможен ли такой вариант что первый раз
> сокет не создавля, а при второй попытке создался ??
все что угодно может быть .. нужно анализировать конкретные причины искл-я, возникшего при конструировании объекта, и по результатам анализа уже принимать решение .. например, если искл-е говорит об "Out of memory" (что крайне маловероятно при грамотном подходе к распределению памяти), бессмысленно повторять попытки конструирования
← →
Delpher_Gray (2004-12-30 13:43) [10]А вот такой теперь вопрос...
Почему если в NextOpp"е не создаётся заного сокет - Sock := TClientSocket.Create(nil), то подключения нет ??
Да и как он может таким образом созжаваться, когда он не освобождается ? или всё верно, так и должно быть... !?
NextOpp:
Sock := TClientSocket.Create(nil);
....
....
....
Sock.Open;
← →
Delpher_Gray (2004-12-30 15:32) [11]ауу...
← →
Digitman © (2004-12-30 15:36) [12]
> Почему если в NextOpp"е не создаётся заного сокет - Sock
> := TClientSocket.Create(nil), то подключения нет ??
откуда ж оно возьмется ? если ты не создал объект, реализующий логику подключения ?
> Да и как он может таким образом созжаваться, когда он не
> освобождается ?
так ... стоп ... мы тут о чем вообще ?
о создании некоего VCL-объекта или о логике исполнения некоего метода УЖЕ СУЩЕСТВУЮЩЕГО VCL-объекта ?
причем неважно какого метода - коннект делающего или что-то еще ?
← →
Delpher_Gray (2004-12-30 15:59) [13]
> откуда ж оно возьмется ? если ты не создал объект, реализующий
> логику подключения ?
Ну ведь у меня есть сокет, и я пытаюсь переставить Host и Port и заного открыть сокет. Невыходит, а почему ?
← →
Digitman © (2004-12-30 16:29) [14]
> Delpher_Gray (30.12.04 15:59) [13]
> Ну ведь у меня есть сокет
дык, ешкин кот, ты ж его получил УСПЕШНЫМ вызовов конструктора ?
> я пытаюсь переставить Host и Port
КАКОГГО объекта ? реально ли созданного и существующего ?
и заного открыть сокет
"открыть сокет", если я правильно "въехал" с т.з. ТРАДИЦИОННОЙ терминологии, сводится к вызову тобой некоего метода Open() некоего объекта класса-наследника TClientSocket
отсюда и вопрос - какое, нафих, отношение имеет вызов некоего метода объекта к факту НЕсоздания объекта этого самого класса ? ты можешь это прокомментировать ?
← →
Delpher_Gray (2004-12-30 16:40) [15]Что-то я совсем запутался =)
Сокет (Sock) уже существоет создавать его не нужно, так ?
Теперь я пытаюсь сделать Sock.Open, ведь в момент выполнения открытия сокета, соединения нет, т.к. открываю я заного сокет на событии OnDisconnect.
Вобщем как правильно сделать ?
← →
Digitman © (2004-12-30 16:51) [16]
> Сокет (Sock) уже существоет создавать его не нужно, так ?
так.
> Теперь я пытаюсь сделать Sock.Open
да.
> в момент выполнения открытия сокета
определись, что ты подразумеваешь под "открытием сокета" ?
← →
Delpher_Gray (2004-12-30 17:07) [17]ну ведь сокет открыть/активировать можно только:
Sock.Open();
Sock.Active := true;
или подругому нужно делать ?
← →
Digitman © (2004-12-30 17:14) [18]да.
именно так.
но ведь ты в [8] и [10] завел речь отнюдь не о вызове метода объекта и не об обращении к его св-ву ! А о создании объекта как такового ..
Одно из 2-х - либо ты не в состоянии сформулировать вопрос кратко и внятно, либо у меня уже началось празднование НГ)
← →
Delpher_Gray (2004-12-30 17:21) [19]
> Одно из 2-х - либо ты не в состоянии сформулировать вопрос
> кратко и внятно, либо у меня уже началось празднование НГ)
:) Я и сам хочу уже праздновать, но нужно писать... Срочно =)
в [10] я привл пример, как будет работать. если в процедуре NextOpp будет код://устанавливаю хосит и порт
Sock.OnConnect := SockConnect;
Sock.OnDisconnect := SockDisconnect;
Sock.OnError := SockError;
Sock.OnRead := SockRead;
Sock.OnWrite := SockWrite;
Sock.Open;
То после 1-го подключения дальше ничего не будет. Код выполнится а реакций на него нуль :( То есть никаких событий, ни OnConnect, ни OnDisconnect и т.п.
А если вставить строчку Sock := TClientSocket.Create(nil), то работает... Но строчку эту писать не нужно, уж без неё как-нибудь =)
← →
Delpher_Gray (2004-12-30 19:18) [20]аууу...
← →
Digitman © (2004-12-31 08:17) [21]не понимаю, чего ты снова экспериментируешь ?)
чем тебе [3] не нравится ?
> То есть никаких событий, ни OnConnect, ни OnDisconnect
откуда ж они возьмутся, если коннекта реально не происходит из-за недоступности сервера ? .. ведь в этом случае будет вызвана SockError, где ты и "гасишь" ошибку, т.е. то самое что тебе и нужно было судя по первоначально сформулированной тобой задаче..
Страницы: 1 вся ветка
Форум: "Сети";
Текущий архив: 2005.03.06;
Скачать: [xml.tar.bz2];
Память: 0.52 MB
Время: 0.045 c