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, всичко друго е неуспешно.

Също така не успях да принудя windows/системата/indy да не буферира/кешира съдържание, така че в крайна сметка просто стартирайте програмата за проверка на всеки 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 HEADER на страницата между ‹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