一段简单的代码,调用 API 来实现 PING 指定的主机。
[C++ Builder 版]
#include
#include
#pragma comment(lib, "iphlpapi.lib")
#pragma comment(lib, "ws2_32.lib")
// ---------------------------------------------------------------------------
int __fastcall Ping(const AnsiString AHost) {
HANDLE hIcmp = IcmpCreateFile();
int ARetVal;
if (hIcmp != INVALID_HANDLE_VALUE) {
try {
char AData[32] = "ICMP Data";
DWORD Addr = inet_addr(AHost.c_str());
if (Addr == INADDR_NONE) {
hostent *ent = gethostbyname(AHost.c_str());
if (ent && (ent->h_addrtype == AF_INET)) {
Addr=*((DWORD *)ent->h_addr_list[0]);
}
else {
ARetVal = GetLastError();
return ARetVal;
}
}
DWORD AReplySize = sizeof(ICMP_ECHO_REPLY)+sizeof(AData);
char AReply[sizeof(ICMP_ECHO_REPLY)+sizeof(AData)];
ARetVal = IcmpSendEcho(hIcmp, Addr, &AData, sizeof(AData), NULL,
AReply, AReplySize, 1000);
if (ARetVal == 0)
ARetVal = GetLastError();
else
ARetVal = 0;
}
__finally {
IcmpCloseHandle(hIcmp);
}
}
else
ARetVal = GetLastError();
return ARetVal;
}
[Delphi 版]
uses iphlpapi, winsock;
const
ICMPDLL = 'icmp.dll';
type
PIPOptionInformation = ^TIPOptionInformation;
TIPOptionInformation = packed record
TTL: Byte;
TOS: Byte;
Flags: Byte;
OptionsSize: Byte;
OptionsData: PChar;
end;
ICMP_ECHO_REPLY = packed record
Address: DWORD;
Status: DWORD;
RTT: DWORD;
DataSize: Word;
Reserved: Word;
Data: Pointer;
Options: TIPOptionInformation;
end;
TIcmpEchoReply = ICMP_ECHO_REPLY;
PIcmpEchoReply = ^TIcmpEchoReply;
function IcmpCreateFile: THandle; stdcall; external ICMPDLL;
function IcmpCloseHandle(IcmpHandle: THandle): Boolean; stdcall;
external ICMPDLL;
function IcmpSendEcho(IcmpHandle: THandle; DestinationAddress: DWORD;
RequestData: Pointer; RequestSize: Word; RequestOptions: PIPOptionInformation;
ReplyBuffer: Pointer; ReplySize: DWORD; Timeout: DWORD): DWORD; stdcall;
external ICMPDLL;
// ---------------------------------------------------------------------------
function Ping(const AHost: AnsiString): Integer;
var
hIcmp: THandle;
AData: array [0 .. 31] of Byte;
AReply: array [0 .. sizeof(ICMP_ECHO_REPLY) + 31] of Byte;
Addr: Cardinal;
ent: PHostEnt;
AReplySize: Integer;
begin
hIcmp := IcmpCreateFile;
if hIcmp <> INVALID_HANDLE_VALUE then
begin
try
Addr := inet_addr(PAnsiChar(AHost));
if Addr = INADDR_NONE then
begin
ent := gethostbyname(PAnsiChar(AHost));
if Assigned(ent) and (ent.h_addrtype = AF_INET) then
Addr := PCardinal(ent.h_addr_list[0])^
else
begin
Result := GetLastError;
Exit;
end;
end;
AReplySize := sizeof(ICMP_ECHO_REPLY) + sizeof(AData);
Result := IcmpSendEcho(hIcmp, Addr, @AData[0], sizeof(AData), nil,
@AReply[0], AReplySize, 1000);
if Result = 0 then
Result := GetLastError()
else
Result := 0;
finally
IcmpCloseHandle(hIcmp);
end;
end
else
Result := GetLastError();
end;
成功,返回0,失败返回错误代码,参数可以是主机名或IP地址。如果是主机名,则会解析成IP地址才能。
注意无论那个版本,都要先调用 WSAStartup,在不需要时调用WSACleanup,这个常识就不说了。
Copyright © 2014 DelphiW.com 开发 源码 文档 技巧 All Rights Reserved
晋ICP备14006235号-8 晋公网安备 14108102000087号
执行时间: 0.053965091705322 seconds