如何监控计算机是否连上internet?(30分)

  • 主题发起人 青山侠客
  • 开始时间

青山侠客

Unregistered / Unconfirmed
GUEST, unregistred user!
在一个局域网中,如何在internet服务器或客户机上监控它是否连上internet,上网方式为asdl,
如果采用拨号上网又如何监控呢?
--------------------
请指点!
 
//用这么一个函数。
begin
if GetSystemMetrics(SM_NETWORK) and $0001 = $0001 then
ShowMessage('Machine is Online')
else
ShowMessage('Machine is Offline');
end;
 
use wininet
...
function InternetGetConnectedState(lpdwFlags: LPDWORD;
dwReserved: DWORD): BOOL; stdcall;
{$EXTERNALSYM InternetGetConnectedState}

{ Flags for InternetGetConnectedState }
const
INTERNET_CONNECTION_MODEM = 1;
{$EXTERNALSYM INTERNET_CONNECTION_MODEM}
INTERNET_CONNECTION_LAN = 2;
{$EXTERNALSYM INTERNET_CONNECTION_LAN}
INTERNET_CONNECTION_PROXY = 4;
{$EXTERNALSYM INTERNET_CONNECTION_PROXY}
INTERNET_CONNECTION_MODEM_BUSY = 8;
{$EXTERNALSYM INTERNET_CONNECTION_MODEM_BUSY}
 
俺的代码:
//******************************************************************************
//1、本系统用于检测本机同Internet之间的连接是否畅通(每隔5分钟检测一次)
//2、本系统使用了以下几种技术:
//2。1、TTS发音技术;使用TTS发音引擎将指定文字内容(英文)转换成语音信号;
//2。2、Ping技术:使用ICS控件包中的Ping控件测试本机到指定地址的远程终端是否连通;
//2。3、将wave文件做到exe文件里;
//2。4、缩小图标到系统托盘。
//2。5、写注册表,是本系统在操作系统启动后自行启动;
//******************************************************************************

unit uTestNetwork;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
ExtCtrls, Ping, CoolTrayIcon, StdCtrls, OleCtrls, VTxtAuto_TLB, comobj,
ActiveX, Menus, mmsystem, Registry, AMAboutDialog;

type
TfrmMain = class(TForm)
CoolTrayIcon1: TCoolTrayIcon;
Ping1: TPing;
Timer1: TTimer;
Panel1: TPanel;
PopupMenu1: TPopupMenu;
Close1: TMenuItem;
N1: TMenuItem;
About1: TMenuItem;
AboutDlg: TAMAboutDialog;
procedure Timer1Timer(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure Close1Click(Sender: TObject);
procedure About1Click(Sender: TObject);
private
{ Private declarations }
Connected: Boolean;
PtrSound : PChar;
hRes : THandle; {handle to the loaded resource if 0 indicates nothing playing}
procedure WriteRegistry;
procedure TellAll;
procedure TestConnect;
public
{ Public declarations }
end;

var
frmMain: TfrmMain;
IVTxtAuto1:IVTxtAuto;
implementation

{$R *.DFM}
{$R Ring.RES}

//写注册表
procedure TfrmMain.WriteRegistry;
var
Reg: TRegistry;
begin
Reg := TRegistry.Create;
try
Reg.RootKey := HKEY_LOCAL_MACHINE;
if Reg.OpenKey('/Software/Microsoft/Windows/CurrentVersion/Run', True)
then Reg.WriteString('TestConnect','"' + ParamStr(0) + '"');
finally
Reg.CloseKey;
Reg.Free;
inherited;
end;
end;

//发音
procedure TfrmMain.TellAll;
begin
IVTxtAuto1:=nil;
CoInitialize(nil);//初始化COM库
OleCheck(CoCreateInstance(CLASS_VTxtAuto_, nil, CLSCTX_ALL, IID_IVTxtAuto, IVTxtAuto1));
//创建IVTxtAuto接口
IVTxtAuto1.Register('Demo1',Application.ExeName);
//向服务器注册
IVTxtAuto1.Set_Enabled(1);//使能TTS功能
IVTxtAuto1.Set_Speed(150);//设置语音速度
IVTxtAuto1.Speak('Net is Connected!',vtxtsp_VERYHIGH);//发声
end;

//测试连通状态
procedure TfrmMain.TestConnect;
var
i:integer;
bConnect:boolean;
begin
//连续测试四次,如果有一次Ping通,就认为网络是通的
bConnect:=False;
i:=1;
while (not bConnect) and (i<=4) do
begin
Ping1.Ping;
if Ping1.ErrorCode=0 then bConnect:=True
Inc(i);
end;
//状态处理
if not bConnect
then Connected:=False
else begin
if not Connected
then begin
//如果是第一次Ping通,先播放一段音乐,再使用语音提示
SndPlaySound(PtrSound,SND_ASYNC or SND_MEMORY);
TellAll;
Connected:=True;
end
end;
end;

//每五分钟测试一次
procedure TfrmMain.Timer1Timer(Sender: TObject);
begin
TestConnect;
end;

//初始化
procedure TfrmMain.FormCreate(Sender: TObject);
var
hResInfo : THandle;
begin
Connected:=False;

Ping1.Address:='202.96.209.5'; //上海热线DNS服务器地址
Ping1.TimeOut:=5000;
Ping1.Size :=32;

CoolTrayIcon1.Icon:= Application.Icon;
CoolTrayIcon1.Hint:= Application.Title;

hResInfo := FindResource(HInstance, 'ring', 'WAVE');
hRes := LoadResource(HInstance, hResInfo);
if hRes > 32 then {its a good load}
PtrSound:=LockResource(hRes); {lock the resource}

WriteRegistry;
TestConnect;
end;

//退出系统
procedure TfrmMain.Close1Click(Sender: TObject);
begin
Application.Terminate;
end;

//显示系统关于对话框:使用AMAboutDialog控件
procedure TfrmMain.About1Click(Sender: TObject);
begin
AboutDlg.AppName :='watter 版权所有!';
AboutDlg.Caption :=Application.Title;
AboutDlg.Icon :=Application.Icon ;
AboutDlg.ExtraInfo :='本系统可以检测网络的连通状况';
AboutDlg.Execute ;
end;

end.
 
to watter:你的代码很好,但似乎tping和VTxtAuto_TLB是外来控件delphi本身没有
 
uses WinInet;
if InternetCheckConnection('http://www.yahoo.com.cn/', 1, 0) then //找一个快的服务器就行
showmessage('Connected')
else
showmessage('Disconnected');
更简单,直接取结果。
 
TPing是ICS控件包里的;
VTxtAuto_TLB就是金山词霸的语音引擎。
 
网上搜集来的文章:

检测计算机是否联网比较简单的做法可以通过一个 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。

 
uses WinInet;

function GetNetStatus : Boolean;
var ConnectType : Integer;
begin
ConnectType := INTERNET_CONNECTION_MODEM +
INTERNET_CONNECTION_LAN +
INTERNET_CONNECTION_PROXY;
if (InternetGetConnectedState(@ConnectType, 0) = False) then
Result := False
else
Result := True;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
if GetNetStatus then
ShowMessage('is Connected')
else ShowMessage('not Connected');
end;

end.
 
这个问题应该比较难,在我用过的软件中只有ICQ检查的很准,很它的包括很多NB的软件:OICQ、
Norton、等都不行!
 
如果是要检测某地址的某个端口是否打开要如何做
 
to watter
调用SndPlaySound()时,老是说没有声明,该怎样用它呢
 
to adrich: it in unit "MMSystem"
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
1K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
969
SUNSTONE的Delphi笔记
S
顶部