Skuteczne sprawdzanie połączenia z Internetem.

0

Witam, szukam skutecznej metody sprawdzania połączenia z internetem takiej która mogła by działać w pętli lub w timerze co kilka sec i zwracała do wartość true (connect) lub false (disconnect) w zależności od statusu połączenia z internetem.

Ma ktoś jakiś dobry pomysł?

Metoda którą stosuje to:

For example,

uses WinInet;

function DownloadFile(const Url: string): string;
var
NetHandle: HINTERNET;
UrlHandle: HINTERNET;
Buffer: array[0..1024] of Char;
BytesRead: dWord;
begin
Result := '';
NetHandle := InternetOpen('Delphi 5.x', INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);

if Assigned(NetHandle) then
begin
UrlHandle := InternetOpenUrl(NetHandle, PChar(Url), nil, 0, INTERNET_FLAG_RELOAD, 0);

if Assigned(UrlHandle) then
  { UrlHandle valid? Proceed with download }
begin
  FillChar(Buffer, SizeOf(Buffer), 0);
  repeat
   // Result := Result + Buffer;  (tu wstawiam procedure reconnect)
    FillChar(Buffer, SizeOf(Buffer), 0);
    InternetReadFile(UrlHandle, @Buffer, SizeOf(Buffer), BytesRead);
  until BytesRead = 0;
  InternetCloseHandle(UrlHandle);
end
else
  { UrlHandle is not valid. Raise an exception. }
  raise Exception.CreateFmt('Cannot open URL %s', [Url]);

InternetCloseHandle(NetHandle);

end
else
{ NetHandle is not valid. Raise an exception }
raise Exception.Create('Unable to initialize Wininet');
end;

z tym że program po godzinnym działaniu wywala komunikat: "brak miejsca dla wykonania tego polecenia" domyslam się że przyczyną jest to że nie zwalniam biblioteki winsock? lub ze program działa w timerze co kilka sec:

procedure Tkk.PingerTimerTimer(Sender: TObject);
begin
begin
DownloadFile('http://www.google.pl');
end;
end;

Ktoś może wie jak to zaprogramować żeby co np. 15sec sprawdzać połączenie przez funkcję "DownloadFile('http://www.google.pl');"
i żeby program działał stabilnie?

0

Podobny wątek był poruszany całkiem niedawno tutaj;

Stuprocentowo skuteczną metodę ciężko znaleźć, bo zawsze coś może nawalić i okłamać, ale chyba najlepszym rozwiązaniem jest albo od razu próba wykonania tego, co potrzeba albo pingowania znanych i stabilnych serwerów (jak np. Google przez domenę) lub tego, do którego będziemy chcieli się połączyć; Ale nawet, gdy połączenie jest to mogą zdarzyć się opóźnienia, przez co metoda może przekłamywać - trzeba określić jakiś timeout;

4

Witam, szukam skutecznej metody sprawdzania połączenia z internetem

Powiedzmy że nagle Ziemia podzieliła się na dwie półkule które straciły ze sobą kontakt. Czy w takim wypadku jest internet czy nie?
Nie można odpowiedzieć na to pytanie, można tylko stwierdzić czy masz do czegoś połączenie czy nie.

Co do rozwiązania dragona, ono wskazuje lokalne połączenie, ale również można traktować swój LAN jako WAN a całą resztę jako LAN. Ot po prostu, wszystkim poza mną wysiadł internet.

Więc nie ma tzw. skutecznej metody bo nie możesz stwierdzić co jest internetem. Możesz tylko sprawdzić czy masz połączenie z danym hostem, chociaż on też może naumyślnie ci nie odpowiadać etc.

0

Skoro musimy podłączyć się do naszego serwera to nie ma sensu sprawdzać co słychać na onet - albo po prostu próbować łączyć się ze swoim serwerem bezpośrednio i wyłapywać błędy/wyjątki, albo najpierw go pingować i jeśli odpowie to np. uruchomić wątek pobierania;

A co, jeśli na DNS Google odpowiedzą, onet czy wp także, a podczas próby połączenia ze swoim serwerem wyłoży się? Wtedy niby połączenie z "internetem" jest, ale nie z naszym serwerem; Dla mnie sprawa jest prosta - najbardziej racjonalnym rozwiązaniem jest sprawdzenie połączenia z tym serwer, od którego "coś chcemy";

0

Do tego dodałbym jeszcze problem jakości połączenia - jeśli ssie/śle z prędkością <tu wstaw jakąś śmiesznie małą wartość> to mamy internet czy nie?

0

Do tego dodałbym jeszcze problem jakości połączenia - jeśli ssie/śle z prędkością <tu wstaw jakąś śmiesznie małą wartość> to mamy internet czy nie?

Bah, można się zastanawiać nad pingiem:
Jeżeli wysłałem ping, to zgubił się czy może jeszcze kiedyś wróci? Może jak poczekam z rok to wróci? A może za szybko tracę cierpliwość?

0

Ja tylko dodam od siebie, że metoda, którą podał @_13th_Dragon z funkcją IsConnected będzie nie skuteczna w takim przypadku jaki sprawdzałem u siebie. Przynajmniej kiedyś na XP tak było, ale pewnie niewiele się zmieniło. Mianowicie mam Internet od UPC i komputer jest połączony z ruterem, a dopiero ten ruter oczywiście z modemem. Wystarczy odpiąć modem od rutera i ten kod i tak zwróci True. Mimo iż łączności ze światową siećią wtedy nie ma.

0
function IsConnected: boolean;
const
  // local system uses a modem to connect to the Internet.
  INTERNET_CONNECTION_MODEM      = 1;
  // local system uses a local area network to connect to the Internet.
  INTERNET_CONNECTION_LAN        = 2;
  // local system uses a proxy server to connect to the Internet.
  INTERNET_CONNECTION_PROXY      = 4;
  // local system's modem is busy with a non-Internet connection.
  INTERNET_CONNECTION_MODEM_BUSY = 8;

var
  dwConnectionTypes : DWORD;
begin
  dwConnectionTypes := INTERNET_CONNECTION_MODEM +
                       INTERNET_CONNECTION_LAN +
                       INTERNET_CONNECTION_PROXY;
  Result := InternetGetConnectedState(@dwConnectionTypes,0);
end;

Absolutnie nie należy używać tej funkcji na Neostradzie !

furious programming napisał(a):

A co, jeśli na DNS Google odpowiedzą, onet czy wp także, a podczas próby połączenia ze swoim serwerem wyłoży się? Wtedy niby połączenie z "internetem" jest, ale nie z naszym serwerem; Dla mnie sprawa jest prosta - najbardziej racjonalnym rozwiązaniem jest sprawdzenie połączenia z tym serwer, od którego "coś chcemy";

Najpierw należy sprawdzić serwery, dzięki którym stwierdzimy, że jest internet. Np.; wspomniane google oraz microsoft/wp/onet.
Jeśli którykolwiek z 4 serwerów (im więcej tym lepiej, ale z umiarem do 10 serwerów) odpowiedział = mamy połączenie z internetem.

Następnie sprawdzamy połączenie z naszym serwerem. Jeśli nie ma, należy przekazać użytkownikowi, że wystąpił problem z połączeniem do serwera, a nie z internetem.

Należy odróżniać i przekazywać wyniki, tak, aby użytkownik wiedział na jakim etapie i jaki problem wystąpił.

2

Absolutnie nie należy używać tej funkcji na Neostradzie !

Kolejne blablabla.
Procedura InternetGetConnectedState służy do pobrania informacji o tym czy winda widzi jakąś sieć poza swoim komputerem i do tego się przydaje. Niestety, niektórzy nie są w stanie zrozumieć tego, że obecność internetu to właściwie coś niemożliwego do stwierdzenia i albo odradzają tą funkcję (mimo że robi wszystko dobrze) albo z kolei przypisują jej działanie którego ona nie ma.

Należy odróżniać i przekazywać wyniki, tak, aby użytkownik wiedział na jakim etapie i jaki problem wystąpił.

Ba!

W twoim przypadku załóżmy takie coś. Jestem administratorem serwera. Ze względów bezpieczeństwa na routerze blokuje dostęp do każdego IP poza zaufanymi. Twój program nie zadziała mimo że twój serwer będzie na liście zaufanych. Internet również będzie dostępny bez problemów, po prostu mój router nie pozwala na połączenie.

Niestety, niektórzy po prostu muszą przekombinować rozwiązanie i zamiast zrobić po prostu podłącz się tam gdzie musisz najpierw zrobią miliony kroków które nie wiadomo czemu mają służyć. Ja u siebie w programach często nawet nie sprawdzam czy połączenie się powiodło, po prostu sprawdzam czy odpowiedź była poprawna. Jak była to zakładam że wszystko jest ok jak nie to wywalam "komunikacja z serwerem nie powiodła się" (co może znaczyć że albo nie udało się osiągnąć komunikacji z serwerem lub jego odpowiedź była uszkodzona/niekompletna). No ale wy wolicie zpingować najpierw paręnaście serwerów, policzyć średnią z pingu, sprawdzić czy się zgadza, sprawdzić za pomocą WinAPI czy wszystko jest ok, jeszcze najlepiej szybko wykonać jakiś test prędkości łącza i dopiero wtedy łączyć się z serwerem bo być może uda nam się połączyć. Gratuluje przekombinowania. Jak piszecie hellołworld to pewnie najpierw też sprawdzacie 10 metodami czy uda się wyświetlić komunikat.

0

A czy przypadkiem ta ikonka globu co się pokazuje w zasobniku przy połączeniu sieciowym to nie jest właśnie InternetGetConnectedState? Nie zawsze pokazuje to faktyczny stan i bardzo często z opóźnieniem.

0

Wg mnie to właśnie to, przy czym odpalane raz na jakieś 5 sek.

1 użytkowników online, w tym zalogowanych: 0, gości: 1