可以用类似PING之类的程序检测是否Idtcpclient在线:
Delphi编程实现Ping操作
张泰立
使用过网络的用户都熟悉“Ping”这个指令,它是一个DOS下的可执行文件,一般用
它来检查网络连接的好坏程度。其基本原理是利用TCP/IP协议包中ICMP协议中的一个功
能,即向所指定的计算机发送一个请求,收到请求的计算机返回一个应答,借此来判断该
计算机是否在网上运行或者检查网络连接是否稳定可靠。在Ping程序执行过程中,双方
计算机所耗费的资源都很少,因此,它是一个非常实用的工具。
我们可以通过编程来实现“Ping”操作,对其加以改进,使之具有Windows的界面
风格,显示比DOS更加直观。
首先,对编程中需要的动态链接库作一简要说明:在Windows的System目录下,你
可以找到Icmp.dll文件,该动态链接库提供了ICMP协议的所有功能,我们的编程就建立
在
对该动态链接库的调用上。
Icmp.dll文件内的调用函数说明如下:
1、IcmpCreateFile
打开一个句柄,通过该句柄你可以发送ICMP的请求回送报文。
2、IcmpCloseHandle
关闭你通过IcmpCreateFile函数打开的句柄。
3、IcmpSendEcho
通过你打开的句柄发送ICMP请求,在超时或应答报文接收后返回。其参数基本上和
它的帧结构一致,可参看下面的程序部分,其具体含意你可以参看有关ICMP协议的书
籍。
初步了解了上述的三个函数后,我们就可以开始编程了。
首先,我们的程序运行后应该有如图1所示的基本功能。为此,我们可先在Delphi的
窗口中放入右上图中所示的控件,如按钮、编辑框和文本显示框等。
(G72.JPG)
例程运行示意图
然后,在程序的开始部分(FormCreate)对WinSocket进行初始化,其作用是申明
使用的版本信息,同时调入Icmp.dll库。
type
PIPOptionInformation = ^TIPOptionInformation;
TIPOptionInformation = packed record
TTL: Byte;
TOS: Byte;
Flags: Byte;
OptionsSize: Byte;
OptionsData: PChar;
end;
PIcmpEchoReply = ^TIcmpEchoReply;
TIcmpEchoReply = packed record
Address: DWORD;
Status: DWORD;
RTT: DWORD;
DataSize: Word;
Reserved: Word;
Data: Pointer;
Options: TIPOptionInformation;
end;
TIcmpCreateFile = function: THandle; stdcall;
TIcmpCloseHandle = function(IcmpHandle: THandle): Boolean;
stdcall;
TIcmpSendEcho = function(IcmpHandle:THandle;
DestinationAddress: DWORD;
RequestData: Pointer;
RequestSize: Word;
RequestOptions: PIPOptionInformation;
ReplyBuffer: Pointer;
ReplySize: DWord;
Timeout: DWord
): DWord; stdcall;
TMyPing = class(TForm)
Panel1: TPanel;
Label1: TLabel;
PingEdit: TEdit;
ExeBtn: TButton;
Button2: TButton;
Button3: TButton;
StatusShow: TMemo;
procedure Button3Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure ExeBtnClick(Sender: TObject);
private
{ Private declarations }
hICMP: THANDLE;
IcmpCreateFile : TIcmpCreateFile;
IcmpCloseHandle: TIcmpCloseHandle;
IcmpSendEcho: TIcmpSendEcho;
public
{ Public declarations }
end;
procedure TMyPing.FormCreate(Sender: TObject);
var
WSAData: TWSAData;
hICMPdll: HMODULE;
begin
?
// Load the icmp.dll stuff
hICMPdll := LoadLibrary('icmp.dll');
@ICMPCreateFile := GetProcAddress(hICMPdll, 'IcmpCreateFile');
@IcmpCloseHandle := GetProcAddress(hICMPdll,
'IcmpCloseHandle');
@IcmpSendEcho := GetProcAddress(hICMPdll, 'IcmpSendEcho');
hICMP := IcmpCreateFile;
StatusShow.Text := '';
StatusShow.Lines.Add('目的IP地址 字节数 返回时间(毫秒)');
end;
接下来,就要进行如下所示的Ping操作的实际编程过程了。
procedure TMyPing.ExeBtnClick(Sender: TObject);
var
IPOpt:TIPOptionInformation;// IP Options for packet to send
FIPAddress
WORD;
pReqData,pRevData
Char;
pIPE
IcmpEchoReply;// ICMP Echo reply buffer
FSize: DWORD;
MyString:string;
FTimeOut
WORD;
BufferSize
WORD;
begin
if PingEdit.Text <> '' then
begin
FIPAddress := inet_addr(PChar(PingEdit.Text));
FSize := 40;
BufferSize := SizeOf(TICMPEchoReply) + FSize;
GetMem(pRevData,FSize);
GetMem(pIPE,BufferSize);
FillChar(pIPE^, SizeOf(pIPE^), 0);
pIPE^.Data := pRevData;
MyString := 'Hello,World';
pReqData := PChar(MyString);
FillChar(IPOpt, Sizeof(IPOpt), 0);
IPOpt.TTL := 64;
FTimeOut := 4000;
IcmpSendEcho(hICMP, FIPAddress, pReqData, Length(MyString),
@IPOpt, pIPE, BufferSize, FTimeOut);
if pReqData^ = pIPE^.Options.OptionsData^ then
begin
StatusShow.Lines.Add(PChar(PingEdit.Text) + ' '
+IntToStr(pIPE^.DataSize) + ' ' +IntToStr(pIPE^.RTT));
end;
begin
StatusShow.Lines.Add(PChar(PingEdit.Text) + ' '
+IntToStr(pIPE^.DataSize) + ' ' +IntToStr(pIPE^.RTT));
end;
FreeMem(pRevData);
FreeMem(pIPE);
end
end;
通过上面的编程,我们就实现了Ping功能的界面操作。实际上,ICMP协议的功能还
有很
多,都可以通过对Icmp.dll的函数调用来实现。
------------------------------------------------
问题: 如何在Delphi代码中隐式运行ping命令,并返加 ( 积分: 100 )
分类: 非技术问题
来自: coao, 时间: 2000-04-05 9:39:33, ID: 212797
来自: www, 时间: 2000-04-05 9:46:58, ID: 212804
winexec('ping ...>aa.txt',sw_hide);
然后读取aa.txt
来自: 程旭, 时间: 2000-04-05 10:04:17, ID: 212826
可以用ICMP,你需要的活我可以给你M资料。
来自: Big_Z, 时间: 2000-04-05 11:05:47, ID: 212883
程旭兄,Mail 一个给我吧,先谢了!^_^!
big_z_@21cn.com
来自: SuperMMX, 时间: 2000-04-05 12:46:23, ID: 212962
简单的就用3w的,要保险点的有一个函数叫 createProcessAndWait
在这里找一下吧,都要用文件。
来自: g622, 时间: 2000-04-05 12:54:18, ID: 212978
www的最简单.
来自: Big_Z, 时间: 2000-04-05 13:09:13, ID: 212998
www的简单,
但怎么知道 Ping 完了呢,if “aa.txt” 已经存在?
建议还是不要偷懒,调用进程 Ping
来自: Flintstone, 时间: 2000-04-05 16:08:34, ID: 213102
可以用ics控件包中的ping控件,这个控件比较好的实现了ping的功能。
来自: wrench, 时间: 2000-04-05 17:05:04, ID: 213135
用进程执行Ping并等待
来自: codeguru, 时间: 2000-04-05 19:15:38, ID: 213194
程旭兄,呵呵,麻烦mail一个给我吧,谢谢
blackbull@21cn.com
来自: CaiFeng, 时间: 2000-04-05 20:26:06, ID: 213225
运用系统的重定向和管道技术可以隐藏的Dos控制台
SECURITY_ATTRIBUTES lsa
STARTUPINFO si
通过设置si.wShowWindow=SW_HIDE,可以使得DOS程序在执行时不显示出来
来自: Pipi., 时间: 2000-04-06 0:20:46, ID: 213451
ics 的 TPing 控件最好用:
http://www.rtfm.be/fpiette/indexuk.htm
来自: sunstone, 时间: 2000-04-06 0:48:55, ID: 213477
g
来自: Liu JZX, 时间: 2000-04-06 20:10:13, ID: 214318
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
Function MyPing(const Host:string):boolean;
var
CmdLinePChar:array[0..120] of char;
StartUpInfo:TStartUpInfo;
ProcessInfo:TProcessInformation;
HOutput:THandle;
StringList:TStringList;
TempFileName:String;
i:integer;
begin
Result:=false;
Screen.Cursor:=crHourGlass;
StringList:=TStringList.Create;
try
TempFileName:=ExtractFilePath(application.ExeName)+'tempfile.tmp';
HOutput:=FileCreate(TempFileName);
if HOutput<0 then
exit;
StrPCopy(CmdLinePChar,'Ping.exe'+Host);
FillChar(StartUpInfo,sizeof(StartUpInfo),#0);
with StartUpInfo do
begin
cb:=sizeof(StartUpInfo);
dwFlags:=STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
wShowWindow:=SW_HIDE;
hstdOutput:=HOutput;
end;
if CreateProcess(nil,CmdLinePChar,nil,nil,True,0,nil,nil,StartUpInfo,ProcessInfo) then
begin
WaitForSingleObject(Processinfo.hProcess,INFINITE);
FileClose(HOutput);
end
else
begin
FileClose(HOutput);
exit;
end;
StringList.LoadFromFile(TempFileName);
DeleteFile(TempFileName);
for i:=1 to StringList.Count-1 do
begin
if pos('Reply from',StringList
)>=1 then
begin
Result:=true;
break;
end;
end;
finally
screen.Cursor:=crDefault;
form1.edit1.text:=stringlist;
StringList.Free;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
MyPing(' jsj_ws8');
end;
end.
来自: coao, 时间: 2000-07-21 3:11:42, ID: 288630
问题太久,昨日刚解决
不好意思(现在发分)
来自: coao, 时间: 2000-07-21 3:17:31, ID: 288632
关注此题
来自: coao, 时间: 2000-07-21 3:18:43, ID: 288633
多人接受答案了。
得分大富翁: Big_Z-10,CaiFeng-10,Flintstone-10,Liu JZX-20,Pipi.-10,SuperMMX-10,wrench-10,www-10,程旭-10,