Delphi и indy TIDHTTP: различать сервер не найден и не найдена ошибка ответа

Я использую indy TIDHTTP, чтобы узнать, не работает ли мой сервер в Интернете или адрес страницы на том же сервере недоступен.

Я скопировал предложение, данное в другом потоке в stackoverflow:

try
  IdHTTP1.Get(mypage_address);
except
  on E: EIdHTTPProtocolException do begin
     if e.errorcode=404 then
        showmessage('404 File not found');
    // use E.ErrorCode, E.Message, and E.ErrorMessage as needed...
  end;
end;

но таким образом я могу определить только код ответа сервера, а не то, что сервер вообще не ответил. Я думаю, это тривиально, но я не знаю, как это сделать?


person user1238784    schedule 01.05.2014    source источник
comment
Вы можете попробовать использовать несуществующий URL, например example.com, или проверить исходный код Indy. В Indy исключение EIdHTTPProtocolException может быть выдано в результате HTTP-запроса GET только в том случае, если сервер был найден и действительно отправил ответ.   -  person mjn    schedule 01.05.2014
comment
Привет, как подключение к несуществующему URL-адресу может сказать мне что-нибудь о том, что мой сервер не работает в Интернете? Возможно, вас смутил мой первоначальный вопрос, я отредактировал его, надеясь, что он станет более понятным.   -  person user1238784    schedule 01.05.2014


Ответы (2)


Исключение EIdHTTPProtocolException возникает, когда TIdHTTP успешно отправляет запрос на сервер и отправляет ответ об ошибке HTTP обратно на TIdHTTP. Если сервер вообще недоступен, вместо него будет вызвано другое исключение (обычно EIdSocketError, EIdConnectException или EIdConnectTimeout).

try
  IdHTTP1.Head(mypage_address);
except
  on E: EIdHTTPProtocolException do begin
    ShowMessage(Format('HTTP Error: %d %s', [E.ErrorCode, E.Message]));
  end;
  on E: EIdConnectTimeout do begin
    ShowMessage('Timeout trying to connect');
  end;
  on E: EIdSocketError do begin
    ShowMessage(Format('Socket Error: %d %s', [E.LastError, E.Message]));
  end;
  on E: Exception do begin
    ShowMessage(Format('Error: [%s] %s', [E.ClassName, E.Message]));
  end;
end;
person Remy Lebeau    schedule 01.05.2014
comment
Спасибо, не могли бы вы также помочь мне найти модули, в которых определены EIdConnectTimeout и EIdSocketError? - person user1238784; 01.05.2014
comment
EIdConnectTimeout находится в блоке IdExceptionCore. EIdSocketError находится в блоке IdStack. - person Remy Lebeau; 01.05.2014

Я попытался выполнить проверку сервера/сайта с научной точки зрения. но в конце концов просто пришел к этому:

function TFrameSiteChecker.GetSiteHeader(const AUrl: string): Integer;
begin
  try
    idhttp1.Head(AUrl);
    Result := idhttp1.ResponseCode;
  except
    on E: exception do
      Result := 0;
  end;
end;

Логика заключается в том, что получение головы уменьшает трафик, размеры журналов и т. д.

Есть один правильный результат от функции - возврат кода состояния 200, все остальное - фейл.

Также мне не удалось заставить окна/систему/инди не буферизовать/кэшировать содержимое, поэтому в конечном итоге просто запускайте проверку каждые 30 минут по расписанию. В противном случае (если только что-то еще не очистит кеш) после первого подключения это всегда удается, даже если вы отключите машину от сети!

person Despatcher    schedule 01.05.2014
comment
Привет спасибо. Я не очень хорошо знаком с методом TIdHttp.Head. Должен ли передаваемый URL-адрес иметь тип: mydomain.com или это может быть любая страница, например: mydomain.com/test/script.php ? - person user1238784; 01.05.2014
comment
любая страница должна предоставлять ответ на HEAD - вы просто извлекаете HTML-ЗАГОЛОВОК страницы между ‹HEAD› и ‹/HEAD›, а не всю страницу. - person Despatcher; 01.05.2014
comment
@Despatcher: Это НЕ то, что делает TIdHTTP.Head(). Он просит сервер отправить только заголовки HTTP для страницы и вообще не отправлять содержимое тела. Это хороший способ проверить существование страницы, не извлекая саму страницу. - person Remy Lebeau; 01.05.2014
comment
Извините, должно быть, устал или старею. Нет содержимого страницы (как я сказал, сбивчиво), он просто получает заголовки, тем самым проверяя доступность страницы. - person Despatcher; 01.05.2014
comment
@Despatcher: да, он извлекает заголовки HTTP, а не заголовки HTML. Большая разница. - person Remy Lebeau; 02.05.2014