Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Internet (https://www.clubdelphi.com/foros/forumdisplay.php?f=3)
-   -   Saber si estoy conectado a Internet (https://www.clubdelphi.com/foros/showthread.php?t=62837)

JPMMVR 16-01-2009 15:42:04

Saber si estoy conectado a Internet
 
No hay manera, he visto varios ejemplos de "Como saber si estas conectado", 2 de ellos en este mismo foro, en trucomania, todos son muy parecidos, pero los he probado todos y todos me dicen que estoy conectado, aunque cierre la conexion, hasta he desconectado la USB inalambrica que tengo para conectarme a Internet.

En este post incluso hay un comentario que dice

Cita:

La función InetIsOffLine solo verifica si hay un cable conectado a la tarjeta de red, siempre indica verdadero.
Esto es exactamente lo que me pasa a mi.

Alguien me puede dar algun consejo o indicarme alguna pagina que indique la solucion real?.

Un saludo a todos.:)

white_zombie 16-01-2009 18:45:25

Hola, se me ocurre que podrias hacer un ping a google o alguna direccion que sepas que nunca va estar caida y si tienes respuesta es que tienes conexion a internet.

Un Saludo.

FENIXadr 12-04-2011 02:55:16

Hola... no se si ya habrás solucionado el problema o si tiene sentido solucionarlo tanto tiempo después.. de todos modos te comento algo que acabo de ver, si ya no te es util, mil disculpas, pero bueno tal vez pueda ayudar a otra persona que busque algo parecido..

Yo estaba buscando como detectar una conexión a internet... pero no quiería poner un timer que registre cada cierto tiempo si estoy o no conectado, ya sea con un ping o alguna otra manera, lo que yo queria era disparar un evento cuando se conectara o desconectara mi PC.. cosa que si miramos desde un punto "literal" no existe... peeeeero.. existe un evento que se dispara si se modifica el registro de windows.. que tendrá que ver.. jeje.. la cosa es que cuando se conecta o desconecta una PC de internet, windows coloca en el registro cierta info... entonces si podemos disparar un evento para ver una clave modificada, si esta clave se modifica en la conexion y desconexion, estaremos disparando un evento justamente cuando nos conectamos o desconectamos...

bueno basta de palabras y a los links..

este link nos lleva a como detectar una activacion de la conexion a internet
http://173-203-208-16.static.cloud-ips.com/0/278523

y este otro a como generar un evento cuando se modifica el registro...
http://delphi.about.com/od/kbwinshell/l/aa052003a.htm

de todos modos en el primer link esta todo listo para la detectar la conexion.. pero puse el segundo por si alguien quiere profundizar en el tema del registro de windows..

si pueden.. comenten.. yo ya me pongo a probar esto.. como les dije al principio .. lo acabo de encontrar.. jeje..
manos a la obra..

saludos..

FENIXadr 12-04-2011 20:38:59

Bueno gente... si ya han viasto los links del post anterior, verán que la cosa no está tan regalada... lo que si, está muuuy interesante..

del Primer link podemos sacar muchisima info sobre nuestras tarjetas de red..
yo hice una Unit con lo más importante para mi caso... pero en la primer link del post anterior tienen toda la unit completa..

pero vamos por paso..

primero hacemos un proyecto nuevo y le ponemos un TMemo o lo que ustedes quieran para mostrar la IP. (yo deje el TMemo del proyecto que estaba haciendo, pero con un TLabel ya nos es suficiente.)
Despues ejecutamos el programa y nos conectamos y desconectamos a internet para ver como funciona...

Unit1

Código Delphi [-]

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, IDStack, StdCtrls, Registry, WinSock, RegMonitorThread, uAdapterInfo;


type
  TForm1 = class(TForm)
    Memo1: TMemo;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    procedure WMREGCHANGE(var Msg : TMessage); message WM_REGCHANGE;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  RegMonitorThread : TRegMonitorThread;
  Conectado : Boolean;
  AdapterData: TAdapterInfo;

implementation

{$R *.dfm}

Function GetIP : String;
var i : Integer;
begin
  Result := '0.0.0.0';
  Conectado := False;
  if Get_EthernetAdapterDetail(AdapterData) then
  begin
    for i := 0 to Length(AdapterData) - 1 do
    begin
      if (AdapterData[i].dwType = 23) or (AdapterData[i].dwType = 28) then
      begin
        Result := AdapterData[i].sIpAddress;
        Conectado := True;
      end;
    end;
  end;
end;



procedure TForm1.FormCreate(Sender: TObject);
begin

  RegMonitorThread := TRegMonitorThread.Create;
  with RegMonitorThread do
  begin
    FreeOnTerminate:=True;
    Wnd := Form1.Handle;
    Key := '\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces';
    RootKey := HKEY_LOCAL_MACHINE;
    WatchSub := True;
    Resume;
  end;

  Memo1.Clear;
  Memo1.Lines.Add(GetIP);

end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  RegMonitorThread.Terminate;
end;



procedure TForm1.WMREGCHANGE(var Msg: TMessage);
begin
  Memo1.Clear;
  Memo1.Lines.Add(GetIP);
end;


end.

y aqui tenemos la otra Unit...


Código Delphi [-]


unit uAdapterInfo;

interface

uses
  Winsock, // Para definir "in_addr"
  Classes,
  SysUtils;


const
  MAX_INTERFACE_NAME_LEN = $100;
  ERROR_SUCCESS   = 0;
  MAXLEN_IFDESCR  = $100;
  MAXLEN_PHYSADDR = 8;

  MIB_IF_OPER_STATUS_NON_OPERATIONAL = 0;
  MIB_IF_OPER_STATUS_UNREACHABLE = 1;
  MIB_IF_OPER_STATUS_DISCONNECTED = 2;
  MIB_IF_OPER_STATUS_CONNECTING  = 3;
  MIB_IF_OPER_STATUS_CONNECTED   = 4;
  MIB_IF_OPER_STATUS_OPERATIONAL = 5;

  MIB_IF_TYPE_OTHER    = 1;
  MIB_IF_TYPE_ETHERNET = 6;
  MIB_IF_TYPE_TOKENRING = 9;
  MIB_IF_TYPE_FDDI     = 15;
  MIB_IF_TYPE_PPP      = 23;
  MIB_IF_TYPE_LOOPBACK = 24;
  MIB_IF_TYPE_SLIP     = 28;

  MIB_IF_ADMIN_STATUS_UP      = 1;
  MIB_IF_ADMIN_STATUS_DOWN    = 2;
  MIB_IF_ADMIN_STATUS_TESTING = 3;

  _MAX_ROWS_ = 20;
  ANY_SIZE   = 1;


type
  MIB_IFROW = record
    wszName:    array[0 .. (MAX_INTERFACE_NAME_LEN * 2 - 1)] of char;
    dwIndex:    longint;
    dwType:     longint;
    dwMtu:      longint;
    dwSpeed:    longint;
    dwPhysAddrLen: longint;
    bPhysAddr:  array[0 .. (MAXLEN_PHYSADDR - 1)] of byte;
    dwAdminStatus: longint;
    dwOperStatus: longint;
    dwLastChange: longint;
    dwInOctets: longint;
    dwInUcastPkts: longint;
    dwInNUcastPkts: longint;
    dwInDiscards: longint;
    dwInErrors: longint;
    dwInUnknownProtos: longint;
    dwOutOctets: longint;
    dwOutUcastPkts: longint;
    dwOutNUcastPkts: longint;
    dwOutDiscards: longint;
    dwOutErrors: longint;
    dwOutQLen:  longint;
    dwDescrLen: longint;
    bDescr:     array[0 .. (MAXLEN_IFDESCR - 1)] of char;
  end;

type
  MIB_IPADDRROW = record
    dwAddr:      longint;
    dwIndex:     longint;
    dwMask:      longint;
    dwBCastAddr: longint;
    dwReasmSize: longint;
    unused1:     word;
    unused2:     word;
  end;


type
  _IfTable = record
    nRows: longint;
    ifRow: array[1.._MAX_ROWS_] of MIB_IFROW;
  end;

type
  _IpAddrTable = record
    dwNumEntries: longint;
    table: array[1..ANY_SIZE] of MIB_IPADDRROW;
  end;


type
  TAdapterInfo = array of record
    dwIndex:    longint;
    dwType:     longint;
    dwMtu:      longint;
    dwSpeed:    extended;
    dwPhysAddrLen: longint;
    bPhysAddr:  string;
    dwAdminStatus: longint;
    dwOperStatus: longint;
    dwLastChange: longint;
    dwInOctets: longint;
    dwInUcastPkts: longint;
    dwInNUcastPkts: longint;
    dwInDiscards: longint;
    dwInErrors: longint;
    dwInUnknownProtos: longint;
    dwOutOctets: longint;
    dwOutUcastPkts: longint;
    dwOutNUcastPkts: longint;
    dwOutDiscards: longint;
    dwOutErrors: longint;
    dwOutQLen:  longint;
    dwDescrLen: longint;
    bDescr:     string;
    sIpAddress: string;
    sIpMask:    string;
  end;


function GetIfTable(pIfTable: Pointer; var pdwSize: longint; bOrder: longint): longint;
  stdcall;
function GetIpAddrTable(pIpAddrTable: Pointer; var pdwSize: longint;
  bOrder: longint): longint; stdcall;

function Get_EthernetAdapterDetail(var AdapterDataFound: TAdapterInfo): boolean;

implementation

function GetIfTable; stdcall; external 'IPHLPAPI.DLL';
function GetIpAddrTable; stdcall; external 'IPHLPAPI.DLL';

function Get_EthernetAdapterDetail(var AdapterDataFound: TAdapterInfo): boolean;
var
  pIfTable: ^_IfTable;
  pIpTable: ^_IpAddrTable;
  ifTableSize, ipTableSize: longint;
  tmp:      string;
  i, j, k, m: integer;
  ErrCode:  longint;
  sAddr, sMask: in_addr;
  IPAddresses, IPMasks: TStringList;
  sIPAddressLine, sIPMaskLine: string;
  bResult:  boolean;
begin
  bResult  := True; //default return value
  pIfTable := nil;
  pIpTable := nil;

  IPAddresses := TStringList.Create;
  IPMasks     := TStringList.Create;

  try
    // First: just get the buffer size.
    // TableSize returns the size needed.
    ifTableSize := 0; // Set to zero so the GetIfTabel function
    // won't try to fill the buffer yet,
    // but only return the actual size it needs.
    GetIfTable(pIfTable, ifTableSize, 1);
    if (ifTableSize < SizeOf(MIB_IFROW) + Sizeof(longint)) then
    begin
      bResult := False;
      Result  := bResult;
      Exit; // less than 1 table entry?!
    end;

    ipTableSize := 0;
    GetIpAddrTable(pIpTable, ipTableSize, 1);
    if (ipTableSize < SizeOf(MIB_IPADDRROW) + Sizeof(longint)) then
    begin
      bResult := False;
      Result  := bResult;
      Exit; // less than 1 table entry?!
    end;

    // Second:
    // allocate memory for the buffer and retrieve the
    // entire table.
    GetMem(pIfTable, ifTableSize);
    ErrCode := GetIfTable(pIfTable, ifTableSize, 1);

    if ErrCode <> ERROR_SUCCESS then
    begin
      bResult := False;
      Result  := bResult;
      Exit; // OK, that did not work.
      // Not enough memory i guess.
    end;

    GetMem(pIpTable, ipTableSize);
    ErrCode := GetIpAddrTable(pIpTable, ipTableSize, 1);

    if ErrCode <> ERROR_SUCCESS then
    begin
      bResult := False;
      Result  := bResult;
      Exit;
    end;

    for k := 1 to pIpTable^.dwNumEntries do
    begin
      sAddr.S_addr := pIpTable^.table[k].dwAddr;
      sMask.S_addr := pIpTable^.table[k].dwMask;

      sIPAddressLine := Format('0x%8.8x', [(pIpTable^.table[k].dwIndex)]) +
        '=' + Format('%s', [inet_ntoa(sAddr)]);
      sIPMaskLine    := Format('0x%8.8x', [(pIpTable^.table[k].dwIndex)]) +
        '=' + Format('%s', [inet_ntoa(sMask)]);

      IPAddresses.Add(sIPAddressLine);
      IPMasks.Add(sIPMaskLine);
    end;

    SetLength(AdapterDataFound, pIfTable^.nRows); //initialize the array or records
    for i := 1 to pIfTable^.nRows do
      try
        //if pIfTable^.ifRow[i].dwType=MIB_IF_TYPE_ETHERNET then
        //begin
        m := i - 1;
        AdapterDataFound[m].dwIndex := 4;//(pIfTable^.ifRow[i].dwIndex);
        AdapterDataFound[m].dwType := (pIfTable^.ifRow[i].dwType);
        AdapterDataFound[m].dwIndex := (pIfTable^.ifRow[i].dwIndex);
        AdapterDataFound[m].sIpAddress :=
          IPAddresses.Values[Format('0x%8.8x', [(pIfTable^.ifRow[i].dwIndex)])];
        AdapterDataFound[m].sIpMask :=
          IPMasks.Values[Format('0x%8.8x', [(pIfTable^.ifRow[i].dwIndex)])];
        AdapterDataFound[m].dwMtu := (pIfTable^.ifRow[i].dwMtu);
        AdapterDataFound[m].dwSpeed := (pIfTable^.ifRow[i].dwSpeed);
        AdapterDataFound[m].dwAdminStatus := (pIfTable^.ifRow[i].dwAdminStatus);
        AdapterDataFound[m].dwOperStatus := (pIfTable^.ifRow[i].dwOperStatus);
        AdapterDataFound[m].dwInUcastPkts := (pIfTable^.ifRow[i].dwInUcastPkts);
        AdapterDataFound[m].dwInNUcastPkts := (pIfTable^.ifRow[i].dwInNUcastPkts);
        AdapterDataFound[m].dwInDiscards := (pIfTable^.ifRow[i].dwInDiscards);
        AdapterDataFound[m].dwInErrors := (pIfTable^.ifRow[i].dwInErrors);
        AdapterDataFound[m].dwInUnknownProtos := (pIfTable^.ifRow[i].dwInUnknownProtos);
        AdapterDataFound[m].dwOutNUcastPkts := (pIfTable^.ifRow[i].dwOutNUcastPkts);
        AdapterDataFound[m].dwOutUcastPkts := (pIfTable^.ifRow[i].dwOutUcastPkts);
        AdapterDataFound[m].dwOutDiscards := (pIfTable^.ifRow[i].dwOutDiscards);
        AdapterDataFound[m].dwOutErrors := (pIfTable^.ifRow[i].dwOutErrors);
        AdapterDataFound[m].dwOutQLen := (pIfTable^.ifRow[i].dwOutQLen);
        AdapterDataFound[m].bDescr := (pIfTable^.ifRow[i].bDescr);

        tmp := '';
        for j := 0 to pIfTable^.ifRow[i].dwPhysAddrLen - 1 do
        begin
          if Length(tmp) > 0 then
            tmp := tmp + '-' + format('%.2x', [pIfTable^.ifRow[i].bPhysAddr[j]])
          else
            tmp := tmp + format('%.2x', [pIfTable^.ifRow[i].bPhysAddr[j]]);
        end;

        if Length(tmp) > 0 then
        begin
          AdapterDataFound[m].bPhysAddr := tmp;
        end;
      except
        bResult := False;
        Result  := bResult;
        Exit;
      end;
  finally
    if Assigned(pIfTable) then
    begin
      FreeMem(pIfTable, ifTableSize);
    end;

    FreeAndNil(IPMasks);
    FreeAndNil(IPAddresses);
  end;

  Result := bResult;
end;


end.


y listo... aqui tenemos un evento que se dispara cuando nos conectamos o desconectamos...

si pueden comenten...

Saludos ..

IVAND 23-04-2011 23:09:06

Hola bastante interesante el tema , lo he probado con una pequena variacion en
RegMonitorThread2 : TRegMonitorThread;

Me indicaba que estaba redeclarado y por eso le cambie el nombre

Arranco el aplicativo y siempre me sale 0.0.0.0

desconecto de internet , quito el cable del router y no sale nada
algo estare haciendo mal ???

Gracias por tu respuesta

Nota : Tema interesante porq de esta manera sabre como activar o desactivar un boton cuando no tengo internet , pero si coneccion a mi red local

FENIXadr 24-04-2011 02:28:56

Hola IVAND.. si te devuelve siempre 0.0.0.0 es posible queAdapterData[i].dwType nunca sea 23 o 28, este evento se dispara solamente si tenés un módem conectado directamente a tu PC, con una conexión "PPP" (23) o "SLIP" (28).
Si no es ninguno de estos valores fijate que valor tiene en tu conexion, en la unit original uAdapterInfo.pas estan las constantes con su descripción.. fijate en los links de los post`s anteriores y bajala.
Bueno espero haberte ayuado..

Espero tu comentario..

Saludos.

glsaavedra 08-10-2011 17:48:52

Nunca es tarde .... a las pruebas me remito .....

estoy necesitando detectar si estoy conectado y cuando quiero recurrir a tu primer link da error 404 al interntar acceder
Algún otro link ?

Saludos y gracias
Guillermo

FENIXadr 08-10-2011 18:40:04

Hola glsaavedra.. si efectivamente parece que han borrado la página.. de todos modos este método funciona si tenés una pc conectada directamente a un modem.. no a un router .. si es asi.. deberia funcionarte lo que arriba esta publicado...
Seria bueno que hagas unas pruebas y comentes que error te da.

Saludos.

escafandra 08-10-2011 19:55:17

Para saber si tienes conexión a internet, lo mas simple es realizar un ping a una dirección conocida y estable. Puedes elegir, por ejemplo www.google.com. Esto funciona relativamente bien siempre y cuando tu conexión no esté controlada por un proxy. Puedes usar cualquier función que te permita realizar un ping. Te recomiendo la lectura de esto.

Un ejemplo de como realizar ping sin componentes, sólo con la API:
Código Delphi [-]
function Ping(Addr: PCHAR; Rep: integer = 3): boolean;
var
  WSA: TWSAData;
  hIcmpFile: Cardinal;
  Reply: ICMP_ECHO_REPLY;
  He: Phostent;
  n: Integer;
begin
  Result:= false;
  if WSAStartup(MAKEWORD(1, 1), WSA) <> 0 then exit;
  He:= gethostbyname(Addr);
  if He = nil then exit;
  hIcmpFile:= IcmpCreateFile;
  n:= 0;
  repeat
    Result:= IcmpSendEcho(hIcmpFile, PULONG(He.h_addr_list^)^, 0, 0, 0, 
                          PCHAR(@Reply), sizeof(ICMP_ECHO_REPLY), 1000) <> 0;
    if Result then
       Result:= Reply.Status = 0;
    inc(n);
  until Result or (n=3);
  IcmpCloseHandle(hIcmpFile);
  WSACleanup;
end;

Un ejemplo de uso sería:
Código Delphi [-]
if Ping('www.google.com') then
    Label1.Caption := 'Exito'
else
    Label1.Caption := 'Fracaso';
Pero si estas detrás de un proxy no va a funcionar pues ping usa el protocolo ICMP para la comunicación, sin embargo Proxy Server sólo soporta paquetes TCP y UDP. La solución va a ser conectarse a una página y ver se se puede leer.

Para este segundo caso diseñé una función que llamé Webing (por paralelismo con la fonética de Ping). Este es el código:

Código Delphi [-]
function WebIng(URL: PCHAR): boolean;
var
  hNet, hUrl: Pointer;
  BytesRead: DWORD;
  Buffer: array [0..64] of char;
begin
  Result:= false;
  BytesRead:= 0;

  if InternetAttemptConnect(0) <> ERROR_SUCCESS then exit;

  hNet:= InternetOpen('WebIng', INTERNET_OPEN_TYPE_PRECONFIG, nil, nil, 0);
  if hNet <> nil then
  begin
    hUrl:= InternetOpenUrl(hNet, URL, nil, 0, INTERNET_FLAG_RELOAD {or INTERNET_FLAG_NO_AUTH}, 0);
    if hUrl <> nil then
    begin
      ZeroMemory(@Buffer[0], sizeof(Buffer));
      Result:= InternetReadFile(hUrl, @Buffer[0], sizeof(Buffer), BytesRead);
      Result:= Result and (BytesRead > 0);
      InternetCloseHandle(hUrl);
    end;
    InternetCloseHandle(hNet);
  end;
  Result:= Result and (Pos('Access Denied', Buffer) = 0);
end;
Y lo usaríamos así:
Código Delphi [-]
  if WebIng(PCHAR('http://www.google.com')) then
    Label1.Caption:= 'Exito'
  else
    Label1.Caption:= 'Fracaso';

En este hilo puedes encontrar mas información y una aplicación de ejemplo que incluso permite autentificarnos en un proxy que así lo exija.

Espero haberte sacado de dudas.


Saludos.




rhino0nt 04-11-2011 20:37:40

RE:Saber si estoy conectado a Internet
 
Te felicito por el código, lo acabo de utilizar y al parecer funciona correctamente, solo es necesario poner la URL junto con el protocolo, es decir, en lugar de 'www.google.com' hay que poner 'http://www.google.com', de otra manera nunca regresa contenido y siempre marca False.

escafandra 05-11-2011 01:22:16

Cita:

Empezado por rhino0nt (Mensaje 417638)
Te felicito por el código...

Gracias.

Cita:

Empezado por rhino0nt (Mensaje 417638)
...funciona correctamente, solo es necesario poner la URL junto con el protocolo, es decir, en lugar de 'www.google.com' hay que poner 'http://www.google.com', de otra manera nunca regresa contenido y siempre marca False.

Tienes razón, se me pasó al escribir el ejemplo. El caso es que al hacer Ping no se debe poner el protocolo y si, al hacer Webing.

Lástima que no puedo editar ese ejemplo de uso. Si algún moderador lo hace evitaría dudas y malentendidos posteriores.


Saludos.

ecfisa 05-11-2011 06:02:22

Cita:

Empezado por escafandra (Mensaje 417665)
Lástima que no puedo editar ese ejemplo de uso. Si algún moderador lo hace evitaría dudas y malentendidos posteriores.

Listo mi amigo, tus pedidos son órdenes ;)

Saludos.:)

escafandra 07-11-2011 13:28:24

Cita:

Empezado por ecfisa (Mensaje 417677)
Listo mi amigo, tus pedidos son órdenes ;)

Saludos.:)


Caramba, ya apareció el genio de la lámpara... :eek: :p

¿Puedo pedir mas cosas? :D:D:D
Me gustaría...... y también.... y ademas....:D:D:D


Gracias.

Saludos.

ecfisa 07-11-2011 19:30:14

Cita:

Empezado por escafandra (Mensaje 417803)
¿Puedo pedir mas cosas? :D:D:D
Me gustaría...... y también.... y ademas....:D:D:D


Gracias.

Saludos.

Mmmm, de eso no me quedó, también se me terminó hace una semana.... :( y además va a entrar en 3 años (mas o menos) :D:D:D

Un saludo.


La franja horaria es GMT +2. Ahora son las 01:59:04.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi