高手指教:有几台服务器(如263和sina),用什么方法可以判断那个服务器速度更快?(100分)

  • 主题发起人 主题发起人 lovesun
  • 开始时间 开始时间
L

lovesun

Unregistered / Unconfirmed
GUEST, unregistred user!
最好帮我做个例子。
 
ping一下就可以了。看返回的时间,最短的一个就是最快的。
 
我也知道用类似PING的功能检查,主要是我不知道怎么做一个类似PING的东西。
 
我有代码,要吗?
 
to:张无忌
谢谢了先
wgang@sinobnet.com
 
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:DWORD;

   pReqData,pRevData:PChar;

   pIPE:PIcmpEchoReply;// ICMP Echo reply buffer

   FSize: DWORD;

   MyString:string;

   FTimeOut:DWORD;

   BufferSize:DWORD;

  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的函数调用来实现。
 
unit Ping;

interface

uses
Windows,Winsock,Sysutils;

Const
{ Exception Message }
SInitFailed = 'Winsock version error';
SInvalidAddr = 'Invalid IP Address';
SNoResponse = 'No Response';
STimeOut = 'Request TimeOut';

type
DWORD=LongWord;
THandle=LongWord;
PIPOptionInformation = ^TIPOptionInformation;
TIPOptionInformation = record
TTL: Byte;
TOS: Byte;
Flags: Byte;
OptionsSize: Byte;
OptionsData: PChar;
end;

PIcmpEchoReply = ^TIcmpEchoReply;
TIcmpEchoReply =
record
Address: DWORD;
Status: DWORD;
RTT: DWORD;
DataSize:Word;
Reserved: Word;
Data: Pointer;
Options: TIPOptionInformation;
end;

function IcmpCreateFile():THandle;stdcall external 'ICMP.dll';
function IcmpCloseHandle(Handle:THandle):Boolean;stdcall external 'ICMP.dll';
function IcmpSendEcho(Handle:THandle;
DestAddr:DWORD;
RequestData: Pointer;
RequestSize: Word;
RequestOptions: PIPOptionInformation;
ReplyBuffer: Pointer;
ReplySize: DWORD;
Timeout: DWORD): DWORD;stdcall external 'ICMP.dll';
procedure ValidCheck();
procedure FreeWinsock();
function PingServer(IPAddr:String;TimeOut:Word):boolean;

var
hICMP:THandle;

implementation

procedure ValidCheck(); //一定要在form.create里加入这个函数
var
WSAData:TWSAData;
begin
if (WSAStartup($202,WSAData)<>0) then
raise Exception.Create(SInitFailed);
hIcmp:=IcmpCreateFile();
if hICMP=INVALID_HANDLE_VALUE then
raise Exception.Create('Create ICMP Failed');
end;

procedure FreeWinsock(); //注意释放资源
begin
IcmpCloseHandle(hIcmp);
WSACleanUP;
end;

function PingServer(IPAddr:String;TimeOut:Word):boolean;
var
IPOpt:TIPOptionInformation;// IP Options for packet to send
FIPAddress:DWORD;
pReqData,pRevData:PChar;
pIPE:PIcmpEchoReply;// ICMP Echo reply buffer
FSize: DWORD;
MyString:string;
FTimeOut:DWORD;
BufferSize:DWORD;
temp:Integer;
pIPAddr:Pchar;
begin
GetMem(pIPAddr,Length(IPAddr)+1);
FillChar(pIPAddr^,Length(IPAddr)+1,0);
StrPCopy(pIPAddr,IPAddr);

FIPAddress := inet_addr(pIPAddr);

FreeMem(pIPAddr);

if FIPAddress=INADDR_NONE then
begin
result:=false;//Exit
exit;
end;


FSize := 40;
BufferSize := SizeOf(TICMPEchoReply) + FSize;
GetMem(pRevData,FSize);
GetMem(pIPE,BufferSize);

FillChar(pIPE^, SizeOf(pIPE^), 0);
pIPE^.Data := pRevData;
MyString := 'Ping Digital Data';
pReqData := PChar(MyString);
FillChar(IPOpt, Sizeof(IPOpt), 0);

IPOpt.TTL := 64;
//time out
FTimeOut := TimeOut;
//go!!!
temp:=IcmpSendEcho(hICMP,//dll handle
FIPAddress,//target
pReqData,//data
Length(MyString),//data length
@IPOpt,//addree of ping option
pIPE,//
BufferSize,//pack size
FTimeOut);//timeout value

if temp=0 then
begin
Result:=false;
exit;
end;

if pReqData^ = pIPE^.Options.OptionsData^ then
Result:=true
else
Result:=false;

FreeMem(pRevData);

FreeMem(pIPE);

end;



end.
使用很简单,
PingServer(FIPlist.Strings,FDelayTime)=TRUE就可以PING通
 
多人接受答案了。
 
后退
顶部