Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Сети";
Текущий архив: 2002.12.19;
Скачать: [xml.tar.bz2];

Вниз

Windows Socket Error 11001 trouble   Найти похожие ветки 

 
Rodion   (2002-08-26 12:10) [0]

Привет, мастера!
При написании простенького приложения для работы с сетью с использованием ClientSocket возникла ситуация, при которой выдается exception "Windows Socket Error: (11001) on API ASync Lookup".
Такое происходит только если из машины, на которой запускаем клиент, выдернуть сетевой шнур.
При этом событие OnError не вызывается.

Как отловить этот exception?


 
Digitman   (2002-08-26 16:29) [1]

cм. ф-цию SetErrorProc()


 
alex_ustasu   (2002-10-22 12:17) [2]

Чья это функция, Digitman ?


 
Digitman   (2002-10-22 12:42) [3]

Replaces the exception handler for error messages that are received from a Windows socket connection.

Unit

ScktComp

Category

exception handling routines

type TSocketErrorProc = procedure(ErrorCode: Integer);
function SetErrorProc(ErrorProc: TSocketErrorProc): TSocketErrorProc;

Description

Call SetErrorProc to assign an exception handler for error messages from Windows socket API calls. By default, socket components have no special error handler and simply raise an ESocketError exception when they receive error messages. If an exception handler is assigned using SetErrorProc, the socket component does not raise this exception.

The ErrorProc parameter specifies the exception handler. It is passed the Windows socket error code. Inside this exception handler an application can compensate for the error or raise an exception. Passing a value of nil for the ErrorProc parameter restores the default behavior, where the socket component raises an ESocketError exception.

SetErrorProc returns the current exception handler. This value is nil when SetErrorProc is called for the first time, and is the value of the ErrorProc parameter from the previous invocation of SetErrorProc thereafter.


 
alex_ustasu   (2002-10-22 13:04) [4]

DigitMan, большое спасибо!!! Никто до вас не мог подсказать, как это сделать. Получилось. Столько времени угрохал и испытал разочарований из-за ерунды. "Трудно быть бестолковым". Однако странно, почему так реализован компонет...


 
Digitman   (2002-10-22 13:07) [5]

Просто хэлп нужно читать)
Он ведь для тебя писан Борландом


 
alex_ustasu   (2002-10-22 13:19) [6]

Cогласен, но не на все 100%. Дискутировать,однако, не буду.


 
alex_ustasu   (2002-10-22 15:45) [7]

Однако теперь происходит такая вещь: 12 раз все срабатывает нормально(опрашиваю 4 порта на каждом сервере), а на 13 все-таки выполняется Raise в процедуре TCustomWinSocket.CMLookupComplete
модуля ScktComp...


 
Digitman   (2002-10-22 16:29) [8]

ну и какова точная диагностика исключения, возникающего "на 13-й раз" ?


 
alex_ustasu   (2002-10-22 16:54) [9]

Да та же самая: 11001 ...Но дело, конечно, не в количестве. Это происходит при обращении к одному конкретному хосту(не знаю, в чем его особенность). При обращении к другим хостам были ошибки 100060 и 100061 (или без ошибки), и они нормально передавались процедуре OnСlientSocketError(если провести инициализацию SetErrorProc). А эта ошибка не перехватывается.


 
Digitman   (2002-10-22 17:07) [10]

А потому что отказ разрешения имени хоста никак не связан с ошибками гнездового транспорта. Разрешение имени хоста в его IP-адрес есть функциональность, независящая от того, есть объект-гнездо или нет его.

Обрати внимание - все, что связано с TSocketErrorProc, используется лишь для перехвата исключений, отражающих контекст ошибок конкретного гнезда (об этом говорит класс исклюяений -ESocketError).

Lookup-же ф-ции не "привязаны" ни к какому конкретному гнезду, задача этих ф-ций - используя DNS-механизм, получить IP-адрес целевого хоста (по его имени) и подставить этот адрес в структуру, используемую для инициализации конкретно создаваемого (уже после этого !) гнезда.


 
alex_ustasu   (2002-10-22 17:46) [11]

Позволю себе тоже обращаться на "ты", если можно.
Ты же сам в своем первом ответе на основной вопрос сделал ссылку на SetErrorProc!
Мне интересно, почему она этот хост не находит(код ведь об этом говорит), когда он "живой" и на IP-сетке! С другого хоста возвращается 100061, и все работает обычным образом.
Каков же выход? Использовать сначала функции из Winsock2 ?


 
Digitman   (2002-10-22 17:58) [12]

>alex_ustasu
Ответь сначала - о чем ты вообще ведешь речь.

Автор (Rodion) вел речь явно о клиенте (см. ссылку в 1-м посте на ClientSocke)

Ты же почему-то - об обработке ошибок на серверной стороне

Цитирую :
>>и они нормально передавались процедуре OnСlientSocketError

OnСlientSocketError - это же событие сервера ! Разве о приложении-сервере мы тут говорим ?

Давай-ка расставляй точки над i сначала..


 
alex_ustasu   (2002-10-23 09:38) [13]

Я говорю о клиенте, конечно. Эта ошибка, вероятно, может быть только у него(если я правильно интерпретирую смысл "Host Not Found"). Я писал "передавались" в том смысле, что вызывается мой обработчик ошибок. Серверный обработчик обзывается ServerSocketClientError.


 
Digitman   (2002-10-23 11:08) [14]

Host not found - ошибка, которая может возникнуть на любой стороне. И возникает она при попытке разрешения имени в IP-адрес.

Касамемо клиента, для реального коннекта с сервером ему требуется именно IP-адрес, а не имя целевого хоста - хоста сервера. И если ты не указал в св-вах клиентского компонента этот IP-адрес, а указал вместо него имя хоста, то перед попыткой коннекта в коде кл.компонента будет вызвана lookup-процедура (WSAAsyncLookup для неблок.режима). Цель ее - используя все доступные клиенту DNS-службы, получить IP-адрес для интересующего имени хоста. И если по тем или иным причинам имя хоста не может быть разрешено в его IP-адрес, то возбуждается как раз то исключение с кодом 11001 (Windows Socket Error: (11001) on API ASync Lookup). Т.е. до попытки коннекта даже дело не доходит !!!! А перехват исключений с пом-ю SetErrorProc() предназначен ТОЛЬКО для последующей собственной обработки искл-й, возможных начиная ИМЕННО С ПОПЫТКИ КОННЕКТА и всех остальных (собственно транспорт и дисконнект), которые могут возникнуть уже после успешного коннекта.

Все исключения гнездового транспорта (см. Winsock.pas), имеют базу BASERR = 10000 и перехватываются с пом.SetErrorProc()

Все прочие исключения, связанные в дан.случае с разрешением имени, имеют базу BASERR = 11000 и перехватываются, например, Application.OnException




 
alex_ustasu   (2002-10-23 12:22) [15]

Если мы говорим о компонентах Delphi ClientSocket и ServerSocket, и я активирую серверный компонент, эта ошибка может возникнуть на его стороне ? Я это не исследовал, конечно, но может быть(если стек не установлен, например ?)...
У меня пока не получилось перехватывать и с Try .. Exception.
Если в цикле ожидания завершения запроса не обрабатывать Application.ProcessMessages, то ожидание бесконечное. А если обрабатывать, то Raise Exception выполняется в процедуре, о которой я упоминал.
Попробую еще раз, может что-то не так делал


 
Digitman   (2002-10-23 13:01) [16]

Нет, на серверной не может. Сервер всегда знает IP-адрес подключившегося к нему клиенту.


 
alex_ustasu   (2002-10-25 10:14) [17]

К сожалению, ни SetErrorProc, ни использование AppException не помогают избавиться от выдачи сообщения об ошибке 11001. Перехват AppException предотвращает лишь выдачу второго сообщения при завершении обработки ошибки. Я предполагаю, что ошбка возникает при отсутствии или какой-то кривизне IP-стека на сервере. Интересено, как же остальные это обходят ? Скорее всего использоанием функций WinSock. Поделился бы кто информацией...


 
Digitman   (2002-10-25 10:50) [18]


> какой-то кривизне IP-стека на сервере


Какой еще "кривизне" ? Какого сервера ? Мы тут о клиенте речь ведем ! Только (!!!!) о клиентском процессе, который вызывает WinsockAPI-ф-цию WSAAsyncGetHostByName() перед connect(), если в TClientSocket указано имя хоста сервера вместо его IP-адреса.
В этом случае Winsock асинхронно известит процесс о результатах разрешения имени посылкой сообщения в окно, организованное объектом TCustomWinSocket, специально для приема нотификаций от Winsock.

Вот штатный обработчик нотификации для данного случая :


procedure TCustomWinSocket.CMLookupComplete(var Message: TCMLookupComplete);
begin
if Message.LookupHandle = FLookupHandle then
begin
FLookupHandle := 0;
if Message.AsyncError <> 0 then //если в ходе разрешения имени хоста/сервиса возник отказ
begin
Disconnect(FSocket); // уничтожить гнездо
raise ESocketError.CreateResFmt(@sWindowsSocketError,
[SysErrorMessage(Message.AsyncError), Message.ASyncError, "ASync Lookup"]); // возбудить исключение с кодом ошибки, возвращенным в Message.AsyncError
end;
if FLookupState = lsLookupAddress then
begin
FAddr.sin_addr.S_addr := Integer(Pointer(PHostEnt(FGetHostData).h_addr^)^);
ASyncInitSocket("", "", FService, FPort, FQueueSize, FClient);
end else if FLookupState = lsLookupService then
begin
FAddr.sin_port := PServEnt(FGetHostData).s_port;
FPort := 0;
FService := "";
ASyncInitSocket("", "", "", 0, FQueueSize, FClient);
end;
end;
end;


как видно, в данной ситуации перехват исключения м.б. осуществлен как минимум установкой обработчика Application.OnException()


 
alex_ustasu   (2002-10-25 11:29) [19]

Digitman, я описал ситуацию, которая возникает у меня.
Мне не нужно приводить этот текст. Именно здесь и происходит выдача злополучного сообщения выполнением raise ESocketError.CreateResFmt. И ничего от этого не спасает, как я написал в предыдущем сообщении: ни установка SetErrorProc, ни перехват Application.OnEception.Может быть, в AppException надо как-то подавить ошибку ?
Да, мы ведем речь о клиенте. И я говорю о том, в каком случае возвращается этот код. Я предполагаю, что код возвращается в случае, если на сервере нет IP(Я сканирую сеть с помощью WNetEnumResource. В полученном списке присутствую все компьютеры сети, и не все они на IP).


 
Digitman   (2002-10-25 11:52) [20]

Вот выдержка из хэлпа :

OnException only handles exceptions that occur during message processing. (1)
Exceptions that occur before or after the execution of the application’s Run method do not generate OnException events. (2)

Условие (1) явно соблюдается
Условие (2) - проверяй сам.

При соблюдении этих условий (и + при условии (3) - CustomWinSocket создан в основном код.потоке процесса), OnException всегда будет генерироваться, вне зависимости от источника исключения.

Вот еще уточнение - вникни в него :

If an exception passes through the try blocks in the application code, the application automatically calls the HandleException method. Unless the exception object is EAbort, HandleException calls the OnException handler, if one exists. Otherwise, it calls ShowException to display a message box indicating an error occurred.

>>предполагаю, что код возвращается в случае, если на сервере >>нет IP(Я сканирую сеть с помощью WNetEnumResource. В >>полученном списке присутствую все компьютеры сети, и не все >>они на IP).

Ну правильно !! Имя машины не есть то же самое, что и имя хоста. Если DNS-сервис (к которорому осуществляется обращение в ходе выполнения WSAAsyncGetHostByName) совместно с DHCP-сервисом в момент запроса может разрешить указанное NetBIOS-имя, результатом будет IP-адрес хоста (ассоциированного с ресурсом), иначе - отказ 11001. Что тут удивительного и непонятного ?


 
alex_ustasu   (2002-10-25 12:45) [21]

Digitman. Начну с последнего замечания(Что тут непонятного). Я написал, что как раз это я понял(я ведь не задал вопрос).
Поскольку ты все объясняешь, как это работает или должно работать, но не нарисуешь работающий пример, который бы решал обозначеннную в основном вопросе темы проблему(что закрыло бы тему сразу), я делаю вывод, что непосредственно с этой проблемой ты лично не сталкивался. Я написал, что использовал все известные мне на данный момент процедуры-перехватчики:
Application.OnException:=AppException;
SetErrorProc(SocketErrorProc);
ClientSocketError
AppException(повторюсь)подавляет выдачу лишь второго сообщения при завершении обработки ошибки обозначеннной библиотечной функцией.
И ни одна из них не решает проблемы. Что конкретно советуешь ?
PS: Работаю с D5 в Windows98 Second Edition.


 
Digitman   (2002-10-25 12:53) [22]

поставь BP на строчке

raise ESocketError.CreateResFmt(@sWindowsSocketError,
[SysErrorMessage(Message.AsyncError), Message.ASyncError, "ASync Lookup"]);

и отрассируй пошагово дальнейший ход выполнения


 
alex_ustasu   (2002-10-25 13:00) [23]

Зачем ? Дальнейшее меня уже не интересует. Сообщение-то выдается...


 
Digitman   (2002-10-25 13:22) [24]

Не хочешь, значит, трассировать ? Или не умеешь ?

Тогда без кода целиком ничего сказать не могу. Говорим с тобой на разных языках.


 
alex_ustasu   (2002-10-25 13:46) [25]

Пора мне высказать недоумение:если я указал, где выдается сообщение, значит я трассировал, наверное.
Вот и я про язык: есть проблема, есть задача, как обойти выдачу этого сообщения об ошибке. Вот и все. Если есть готовый рецепт решения проблемы, буду рад о нем узнать или получить фрагмент кода. Просто надеялся, что кто-то ее уже решил...


 
Digitman   (2002-10-25 14:11) [26]


> есть проблема

Да почему ты считаешь, что это проблема ? Тем более - настолько глобальная, что многие, по-твоему, всенепременно должны были с ней столкнуться ? Не проблема это, а какое-то нарушение логики в твоем собственном коде ! Поэтому и говорю : хочешь помощи - приводи код. Чего из пустого в порожнее перемалывать ?


 
alex_ustasu   (2002-10-25 14:32) [27]

Пожалуйста:
type
server_response_type=(server_notcontacted,server_responsed,server_contacted,server_connected);
var
sever_response:server_response_type;
{-------------------------------------------------------------}
procedure SocketErrorProc(ErrorCode:integer);
begin
server_response:=server_responsed
end;
{-------------------------------------------------------------}
procedure TMain_Form.AppException(Sender: TObject; E: Exception);
begin
if WSAGetLastError <> 0 then SocketErrorProc(WSAGetLastError)
end;
{---------------------------------------------------------------}
procedure TMain_Form.ClientSocketError(Sender: TObject;Socket: TCustomWinSocket;
ErrorEvent: TErrorEvent; var ErrorCode: Integer);
begin
server_response:=server_responsed;
ClientSocket.Socket.Disconnect(Socket.Sockethandle);
ErrorCode:=0
end;
{---------------------------------------------------------------}

SetErrorProc(SocketErrorProc);
Application.OnException:=AppException;
server_response:=server_notcontacted;
try
ClientSocket.Active:=true;
while server_response=server_notcontacted
do Application.ProcessMessages
except on EsocketError do SocketErrorProc(WSAGetLastError)
end;


 
Digitman   (2002-10-25 14:59) [28]

Так, ну и где у тебя тут вызов SetErrorProc() ? Не вижу нигде.
еще раз - см. Digitman © (22.10.02 12:42)


 
Digitman   (2002-10-25 15:01) [29]

извиняюсь. вижу.


 
Digitman   (2002-10-25 15:08) [30]

Т.е., ты хочешь сказать, что сначала ты получаешь диалоговое окно с сообщением об исключении, а уж только потом ты ловишь BP в теле procedure TMain_Form.AppException() ? Правильно я понял ?


 
alex_ustasu   (2002-10-25 15:32) [31]

Я уже писал выше, что если я перехвачу

Application.OnException:=AppException;

то второе диалоговое сообщение об ошибке в этом обработчике не выдается(всего их выдается два, последовательно, если не перехватывать). Но выдача первого диалогового сообщения все-таки производится. И происходит это в процедуре TCustomWinSocket.CMLookupComplete модуля ScktComp.


 
Digitman   (2002-10-25 15:38) [32]

Еще раз - приведи мне дословно текст диагностики исключений обоих диалоговых окон, возникающих при отсутствии перехвата OnException()


 
alex_ustasu   (2002-10-25 15:59) [33]


1) Project ... raised Exception Class ESocketError with message
"Windows Socket Error (11001), оn API "Async LookUp". Process stopped. Use Step or Run to continue

2)Windows Socket Error: (11001), on API "Async LookUp"


 
Digitman   (2002-10-25 16:13) [34]

Что ж ты молчишь-то, что под отладчиком все это делаешь ?)

Я тут, понимаешь ли, парюсь, думаю как ему помочь, а он видите ли даже не удосужился сообимть, что все это - под отладчиком)..
Ты в настройки интегрированного отладчика Делфи ходил ? Настраивал соотв.опции ? Видимо, нет. Потому как первое исключение выбрасывает тебе именно отладчик !!!! А у него - наивысший приоритет, и он перехватывает любые исключения ДО того, как их обработка будет передана в соответствующие процедуры. И эта возможность настраивается (включается/отключается) опционально в меню настроек дебаггера.
Что, по вот этой фразе "Use Step or Run to continue" так трудно было это сообразить ?)



Страницы: 1 вся ветка

Форум: "Сети";
Текущий архив: 2002.12.19;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.55 MB
Время: 0.008 c
14-61791
AL2002
2002-11-28 15:29
2002.12.19
Люди, у меня уже крыша едет...


4-61872
kostik78ua
2002-11-06 16:45
2002.12.19
Internet Explorer


6-61723
Vasechkin
2002-10-01 20:40
2002.12.19
Ну помогите же мне!!!!!


1-61559
Влад2
2002-12-05 22:43
2002.12.19
Команда DOS без окна?


3-61499
Alex2
2002-12-02 15:43
2002.12.19
как принудительно закрыть таблицу





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский