在Win xp下判断当前猫网络是否在线?(100分)

  • 主题发起人 主题发起人 xingxinzhi
  • 开始时间 开始时间
X

xingxinzhi

Unregistered / Unconfirmed
GUEST, unregistred user!
各位大侠:
我用delphi6.0写了个小程序,可以记录当月上网累计时间和次数,但需要手动计时开始和结束,不方便。请问Delphi6怎样在Win xp下判断当前猫网络是否在线,请多多指教
 
很难,目前网络上公布的判断是否在线的函数没有管用的
 
话题1321528的标题是: 请问如何判断是否已连接Internet? (100分)
分类:Internet/TCPIP 叮叮当当 (2002-09-12 19:57:00)
最好是即能判断Modem拨号连接的也能判断宽带接入的,找了些例子都是针对Modem拨号的,ADSL等方式连上Internet都检测不出来。

天堂的小宇 (2002-09-12 19:59:00)
用PING命令就OK了

完颜康 (2002-09-12 20:02:00)
检测计算机的 Internet 连接状态
作者: 940801

检测计算机是否联网比较简单的做法可以通过一个 Win32 Internet(WinInet) 函数 InternetCheckConnection来实现;

这个函数的功能是检查是否能够建立 Internet 连接。

它的实现是在 %SystemRoot%/System32/wininet.dll 中,Delphi 调用声明在 WinInet.pas 中,

其 API 声明如下:

BOOL InternetCheckConnection(

IN LPCSTR lpszUrl,

IN DWORD dwFlags,

IN DWORD dwReserved

);

参数的意义是:

lpszUrl: 需要测试能否建立连接的 URL 地址,可以为空;

dwFlags: 目前只能是 FLAG_ICC_FORCE_CONNECTION(这个常量 Delphi 中没有声明,其值为 $00000001);

dwReserved: 目前只能为 0。

调用的说明:

如果 lpszUrl 是非空的,Windows 从中解析出 Host 名然后 Ping 这个指定的 Host。

如果 lpszUrl 是空的,并且 WinInet 内部服务器的 database 中有一个关于最近的 Server 的纪录,Windows 就从这条纪录中解析出 Host 名然后 Ping 它。

如果能够成功的连接返回 True,否则返回 False;

以下是一个判断当前计算机是否联网的例子:

procedure TForm1.Button1Click(Sender: TObject);

begin

if InternetCheckConnection('http://www.yahoo.com/', 1, 0) then

edit1.text:= 'Connected'

else

edit1.text:= 'Disconnected';

end;

通过上述的方法只能检测出当前计算机是否物理联网,即网线是否接好,网卡是否能顺利工作,不能确定是否能够实现获得 Internet 服务,即是否能和 ISP 进行 Internet 连接。

这时可以通过另一个 Win32 Internet(WinInet) 函数 InternetQueryOption 来检测;

这个函数的功能是查询指定 Internet 句柄的状态、选项。

其 API 声明如下:

BOOL InternetQueryOption(

IN HINTERNET hInternet,

IN DWORD dwOption,

OUT LPVOID lpBuffer,

IN OUT LPDWORD lpdwBufferLength

);

参数的意义是:

hInternet:查询对象的 Internet 句柄(全局查询时为 nil),

dwOption:查询的项目;

lpBuffer:返回的查询结果;

lpdwBufferLength:查询结果的字节长度(包括 IN 和 OUT);

查询成功返回 True,否则返回 False;

我们要查询当前计算机的 Internet 连接状态时可以使用查询项目 INTERNET_OPTION_CONNECTED_STATE,

得到的 ConnectState 返回值可能是以下值的一个或几个值之和:

INTERNET_STATE_CONNECTED :$00000001 连接状态;

INTERNET_STATE_DISCONNECTED :$00000002 非连接状态(和 INTERNET_STATE_CONNECTED 对应);

INTERNET_STATE_DISCONNECTED_BY_USER :$00000010 用户请求的非连接状态

INTERNET_STATE_IDLE :$00000100 连接状态,并且空闲

INTERNET_STATE_BUSY :$00000200 连接状态,正在响应连接请求

以下是一个判断当前计算机是否可以获得 Internet 服务的例子:

function TForm1.CheckOffline: boolean;

var

ConnectState: DWORD;

StateSize: DWORD;

begin

ConnectState:= 0;

StateSize:= SizeOf(ConnectState);

result:= false;

if InternetQueryOption(nil, INTERNET_OPTION_CONNECTED_STATE, @ConnectState, StateSize) then

if (ConnectState and INTERNET_STATE_DISCONNECTED) <> 2 then result:= true;

end;

procedure TForm1.Button1Click(Sender: TObject);

begin

if CheckOffline then

edit1.text:= 'Connect To ISP'

else

edit1.text:= 'Disconnect To ISP';

end;

需要说明的是 InternetQueryOption 函数的检测结果只能表明当前的 Internet 设置是可用的,

并不能表示计算机一定能访问 Internet,例如网线掉了,网卡突然坏了之类的错误就没法检测出来,

要想检测当前计算机是否能够获得 Internet 服务了必须两个函数结合起来使用。

以上程序在 Win2000, Delphi5.0 下调试通过。

最后要提醒大家注意的是在 uses 中要加上 WinInet。

对于 Windows 2000 中网络掉线的实时检测,猜想是和底层的中断或者某个 Service 有关,

但因为本人才疏学浅,一直没能搞懂该怎样做,还请知情的大侠不吝赐教,先在此谢谢您了。

作者:940801 ,Mail:l940801@yahoo.com




叮叮当当 (2002-09-21 16:27:00)
“只能表明当前的 Internet 设置是可用的”是什么意思?另外,第一个函数好像必须依赖于测试的网站是正常的,如果参数里的网站由于某些原因无法访问的话是不是就完了?

Bahl (2002-09-21 17:36:00)
http://www.applevb.com/sourcecode/connect_to_net.zip
这是一个检测是否连接到Internet以及是通过何种方式(Modem,LAN,Proxy)连接到
Internet的VB程序。自己改成Delphi的吧。
石中玉 敬上

叮叮当当 (2002-09-21 18:07:00)
To: Bahl
那段程序确实好用,不过还要花费时间把它转成Delphi……

小雨哥 (2002-09-21 20:18:00)
这么复杂啊。
CSDN 上有简单例子。

千中元 (2002-09-22 13:16:00)
小雨哥csdn上例子的url有么?

我一个程序中用到,通过判断ip来实现,还是有些情况下会判断错误的,
比如Lan的IP地址分配错误的时候

小雨哥 (2002-09-24 3:16:00)
刻了一堆光盘,一时就是找不到了。抱歉,抱歉。 :-)

ugvanxk (2002-09-24 8:40:00)
uses wininet;
function getonlinestate:boolean;
var
contypes:integer;
begin
contypes:=internet_connection_modem+internet_connect_lan+internet_connect_proxy;
if (internetgetconnection(@contypes,0)=false) then
result:=false
else result:=true;
end;
function inetisoffline(flag:integer):boolean;stdcall;external'url.dll';
if inetisoffline(0) then 已连接 else 未连接

千中元 (2002-09-24 23:28:00)
to ugvanxk,
我是通过Lan上网的(整个单位用一个ADSL),
contypes 的值得无论如何组合,结果都为true.
请问你的代码如何区分上网方式?

千中元 (2002-09-25 18:47:00)
老外写的:
uses
WinInet;

const
MODEM = 1;
LAN = 2;
PROXY = 4;
BUSY = 8;

function GetConnectionKind(var strKind: string): Boolean;
var
flags: DWORD;
begin
strKind := '';
Result := InternetGetConnectedState(@flags, 0);
if Result then
begin
if (flags and MODEM) = MODEM then strKind := 'Modem';
if (flags and LAN) = LAN then strKind := 'LAN';
if (flags and PROXY) = PROXY then strKind := 'Proxy';
if (flags and BUSY) = BUSY then strKind := 'Modem Busy';
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
strKind: string;
begin
if GetConnectionKind(strKind) then
ShowMessage(strKind);
end;

louhong (2002-09-25 20:30:00)
一个简单的办法用这个控件:
http://www.utilmind.com/delphi/inetdetector.zip


叮叮当当 (2003-01-14 17:01:00)
To: louhong
用你的控件也不行,在LAN环境里Online一直是True。

gonghh (2003-01-15 13:44:00)
TO 叮叮当当:
楼上几位兄弟贴的东西不行吗????
我也是局域网+ADSL上呀,以下方法没问题呀.

if InternetCheckConnection('http://www.sohu.com',1,0) then
ShowMessage('ON line')
else
ShowMessage('OFF line');
在uses 中加上wininet。




weicong (2003-01-16 17:35:00)
如果是在LAN里,可能要几种方法加起来。[:D]

叮叮当当 (2003-12-01 22:37:00)
楼上各位给的例子应该能应付大多数情况了,Internet连接的类型和情况太多了,我看现在也没有一种方法能100%准确地检测Internet是否连接的,结贴结贴。呵呵!


Bahl-40,gonghh-5,louhong-5,ugvanxk-5,千中元-5,完颜康-40,的回答最终被接受。
 
五种查询Internet连接状态[含IP]的方法


五种查询Internet连接状态[含IP]的方法
版本: 上传者: tomore 上传时间: 2002 三月 28 23:58 访问数: 2210 下载数: 0
开发语言:
大小: 4,011 字节
简介: 1.Powersock 控件法:
这种方法最简单,利用FastNet页的 Powersock控件的LocalIP属性即可判断:
if(Powersock1->LocalIP==&quot;127.0.0.1&quot;):在线
else:离线
特点:[1]判断连接状态,[2]获得本地IP。

2.使用URL.DLL的InetIsOffline(0) 函数:
Win2K:URL.DLL存放在SYSTEM32;
Win9x:URL.DLL存放在SYSTEM;
用GetSystemDirectory(...)得到系统目录。
InetIsOffline(0)返回值:
TRUE: 离线; FALSE:在线。
特点:判断连接状态。

3.WinSock编程法:见程序
特点:[1]判断连接状态;[2]获得本地IP和主机名。

4.WinInet.DLL的InternetGetConnectedState(&dwFlag,0)函数:
注意:为使用该函数,须在项目文件中加入:USELIB(&quot;WinInet.LIB&quot;)
特点:获得较详的连接描述!

5.RASAPI32.DLL的RasEnumConnections函数:
要使用该“枚举所有活动连接”函数,必须:
#include &quot;ras.h&quot;。

若连接数>0:本机当前已连入Internet;
否则: 本机当前未连入Internet;

源码如下,在[BCB5 + WIN2K + 拨号上网]下通过(N字头的为菜单项):

-------------Powersock控件法-----------------------------------------
void __fastcall TForm1::N11Click(TObject *Sender)
{
if(Powersock1->LocalIP==&quot;127.0.0.1&quot;)
ShowMessage(&quot;未连接:&quot;+Powersock1->LocalIP);
else ShowMessage(&quot;已连接:&quot;+Powersock1->LocalIP);
}


-------------URL.DLL的InetIsOffline函数法----------------------------
HINSTANCE hDLL;
typedef bool __stdcall(*FUN)(int); 定义DLL函数指针FUN
FUN isOffLine;
void __fastcall TForm1::N21Click(TObject *Sender)
{
char Buffer[MAX_PATH];
GetSystemDirectory(Buffer,MAX_PATH);
hDLL=LoadLibrary((AnsiString(Buffer)+&quot;/URL.DLL&quot;).c_str());
if(hDLL==NULL){ ShowMessage(&quot;Cannot load URL.DLL! Return... &quot;); return; }
isOffLine=(FUN)GetProcAddress(hDLL,&quot;InetIsOffline&quot;);
if(isOffLine==NULL){ ShowMessage(&quot;Cannot load InetIsOffline(int), Return...&quot;); return; }
if(!isOffLine(0)) ShowMessage(&quot;已连接&quot;);
else ShowMessage(&quot;未连接&quot;);
FreeLibrary(hDLL);
}


------------WinSock法------------------------------------------------
void __fastcall TForm1::N31Click(TObject *Sender)
{
WORD wVersionRequested;
WSADATA wsaData;
wVersionRequested=MAKEWORD(1,1); Start up WinSock
WSAStartup(wVersionRequested,&wsaData);
-----------------------------------------
hostent *p; char *p2; char s[128];
gethostname(s,128); Get the computer name
p=gethostbyname(s);
p2=inet_ntoa(*((in_addr *)p->h_addr)); Get the IpAddress
-----------------------------------------
AnsiString LocationIP=p2;
if(LocationIP==&quot;127.0.0.1&quot;)
ShowMessage(&quot;未连接:&quot;+LocationIP);
else ShowMessage(&quot;已连接:&quot;+LocationIP);
WSACleanup();
}


-----------WinInet.DLL的InternetGetConnectedState函数法----------------
void __fastcall TForm1::N41Click(TObject *Sender)
{
StaticText1->Caption=&quot;&quot;; StaticText2->Caption=&quot;&quot;; StaticText3->Caption=&quot;&quot;;
StaticText4->Caption=&quot;&quot;; StaticText5->Caption=&quot;&quot;; StaticText6->Caption=&quot;&quot;;
StaticText7->Caption=&quot;&quot;;
DWORD dwFlag;
InternetGetConnectedState(&dwFlag,0);
if(dwFlag & INTERNET_CONNECTION_MODEM) StaticText1->Caption=&quot;Yes&quot;; MODEM连接
else StaticText1->Caption=&quot;No&quot;;
if(dwFlag & INTERNET_CONNECTION_LAN) StaticText2->Caption=&quot;Yes&quot;; LAN连接
else StaticText2->Caption=&quot;No&quot;;
if(dwFlag & INTERNET_CONNECTION_PROXY) StaticText3->Caption=&quot;Yes&quot;; 代理连接
else StaticText3->Caption=&quot;No&quot;;
---------检查是否连接-------------------------------------------
if(InternetGetConnectedState(NULL,0)) StaticText4->Caption=&quot;Yes&quot;; 在线
else StaticText4->Caption=&quot;No&quot;;
if(dwFlag & INTERNET_CONNECTION_OFFLINE) StaticText5->Caption=&quot;Yes&quot;;//离线。注:不好用!
else StaticText5->Caption=&quot;No&quot;;
----------------------------------------------------------------
if(dwFlag & INTERNET_RAS_INSTALLED) StaticText6->Caption=&quot;Yes&quot;;
else StaticText6->Caption=&quot;No&quot;;
if(dwFlag & INTERNET_CONNECTION_CONFIGURED) StaticText7->Caption=&quot;Yes&quot;;
else StaticText7->Caption=&quot;No&quot;;
}
----------RASAPI32.DLL的RasEnumConnections函数法---------------------------
#include &quot;ras.h&quot;
void __fastcall TForm1::N51Click(TObject *Sender)
{
RASCONN RASconn[256]; 活动连接数组
DWORD BuffSize; 数组所占内存大小;
DWORD ConnNum; 活动连接数目
RASconn[0].dwSize=sizeof(RASCONN); 必须指定一个连接[数组元素]的内存大小;
BuffSize=sizeof(RASCONN)*256;
DWORD dw
 
后退
顶部