Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Сети";
Текущий архив: 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
3-1107249932
Olka
2005-02-01 12:25
2005.03.06
на запрос в Access появлятеся ошибка Переполнение


3-1107786978
Abusss
2005-02-07 17:36
2005.03.06
ADO+фильтр


3-1107533425
Zif
2005-02-04 19:10
2005.03.06
Нужна помощь с выборкой типа DualListBox.


4-1106240656
Arnold
2005-01-20 20:04
2005.03.06
Проблема с хуком WH_MOUSE


1-1108816012
Bird
2005-02-19 15:26
2005.03.06
Формат Excel-файла





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский