Delphi  实现Ping命令

  1. unit FtPing;
  2.  
  3. interface
  4.  
  5. uses
  6. Windows, SysUtils, Classes, Controls, Winsock, StdCtrls;
  7.  
  8. resourcestring
  9. SICMPRunError = 'ICMP Run Error';
  10. SInitFailed = 'Init Failed. Maybe Winsock Verison Error';
  11. SNoResponse = '[%0:S] No Response';
  12. SInvalidAddr = 'IP Address Error';
  13. SPingResultString = '[%0:S]: Bytes:%1:D Time: %2:Dms TTL:%3:D';
  14.  
  15. type
  16.  
  17. PCnIPOptionInformation = ^TCnIPOptionInformation;
  18. TCnIPOptionInformation = packed record
  19. TTL: Byte; // Time To Live (used for traceroute)
  20. TOS: Byte; // Type Of Service (usually )
  21. Flags: Byte; // IP header flags (usually )
  22. OptionsSize: Byte; // Size of options data (usually , max )
  23. OptionsData: PAnsiChar; // Options data buffer
  24. end;
  25.  
  26. PCnIcmpEchoReply = ^TCnIcmpEchoReply;
  27. TCnIcmpEchoReply = packed record
  28. Address: DWORD; // replying address
  29. Status: DWORD; // IP status value (see below)
  30. RTT: DWORD; // Round Trip Time in milliseconds
  31. DataSize: Word; // reply data size
  32. Reserved: Word;
  33. Data: Pointer; // pointer to reply data buffer
  34. Options: TCnIPOptionInformation; // reply options
  35. end;
  36.  
  37. TIpInfo = record
  38. Address: Int64;
  39. IP: string;
  40. Host: string;
  41. end;
  42.  
  43. TOnReceive = procedure( Sender: TComponent; IPAddr, HostName: string; TTL, TOS: Byte ) of object;
  44.  
  45. TOnError = procedure( Sender: TComponent; IPAddr, HostName: string; TTL, TOS: Byte; ErrorMsg: string ) of object;
  46.  
  47. //==============================================================================
  48. // Ping 通讯类
  49. //==============================================================================
  50.  
  51. { TFtPing }
  52.  
  53. TFtPing = class( TComponent )
  54. {* 通过调用ICMP.DLL库中的函数来实现Ping功能。}
  55. private
  56. hICMP: THANDLE;
  57. FRemoteHost: string;
  58. FRemoteIP: string;
  59. FIPAddress: Int64;
  60. FTTL: Byte;
  61. FTimeOut: DWord;
  62. FPingCount: Integer;
  63. FDelay: Integer;
  64. FOnError: TOnError;
  65. FOnReceived: TOnReceive;
  66. FDataString: string;
  67. FWSAData: TWSAData;
  68. FIP: TIpInfo;
  69.  
  70. procedure SetPingCount( const Value: Integer );
  71. procedure SetRemoteHost( const Value: string );
  72. procedure SetTimeOut( const Value: DWord );
  73. procedure SetTTL( const Value: Byte );
  74. procedure SetDataString( const Value: string );
  75. procedure SetRemoteIP( const Value: string );
  76. function PingIP_Host( const aIP: TIpInfo; const Data; Count: Cardinal; var aReply: string ): Integer;
  77. {* 以设定的数据Data(无类型缓冲区)Ping一次并返回结果。Count表示数据长度 }
  78. function GetReplyString( aResult: Integer; aIP: TIpInfo; pIPE: PCnIcmpEchoReply ): string;
  79. {* 返回结果字符串。}
  80. function GetDataString: string;
  81. function GetIPByName( const aName: string; var aIP: string ): Boolean;
  82. {* 通过机器名称获取IP地址}
  83. function SetIP( aIPAddr, aHost: string; var aIP: TIpInfo ): Boolean;
  84. {* 通过机器名称或IP地址填充完整IP信息}
  85. protected
  86.  
  87. public
  88. constructor Create( AOwner: TComponent ); override;
  89. destructor Destroy; override;
  90.  
  91. function IsOnline: Boolean;
  92.  
  93. function Ping( var aReply: string ): Boolean;
  94. {* 进行循环Ping,循环次数在PingCount属性中指定。}
  95. function PingOnce( var aReply: string ): Boolean; overload;
  96. {* 以设定的数据Ping一次并返回结果。}
  97. function PingOnce( const aIP: string; var aReply: string ): Boolean; overload;
  98. {* 向指定IP进行一次Ping并返回结果。}
  99. function PingFromBuffer( var Buffer; Count: Longint; var aReply: string ): Boolean;
  100. {* 以参数Buffer的数据Ping一次并读取返回结果。}
  101. published
  102. property RemoteIP: string read FRemoteIP write SetRemoteIP;
  103. {* Ping的目标主机地址,只支持ip}
  104. property RemoteHost: string read FRemoteHost write SetRemoteHost;
  105. {* ping的目标主机名,有主机名存在时会覆盖 RemoteIP 的内容}
  106. property PingCount: Integer read FPingCount write SetPingCount default ;
  107. {* 调用Ping方法时进行多少次数据发送,默认是4次。}
  108. property Delay: Integer read FDelay write FDelay default ;
  109. {* 相邻两次 Ping 间的时间间隔,单位毫秒,默认 0 也就是不延时}
  110. property TTL: Byte read FTTL write SetTTL;
  111. {* 设置的TTL值,Time to Live}
  112. property TimeOut: DWord read FTimeOut write SetTimeOut;
  113. {* 设置的超时值}
  114. property DataString: string read GetDataString write SetDataString;
  115. {* 欲发送的数据,以字符串形式表示,默认为"CnPack Ping"。}
  116. property OnReceived: TOnReceive read FOnReceived write FOnReceived;
  117. {* Ping一次成功时返回数据所触发的事件}
  118. property OnError: TOnError read FOnError write FOnError;
  119. {* Ping出错时返回的内容和信息。包括目的未知、不可达、超时等。}
  120. end;
  121.  
  122. implementation
  123.  
  124. {$R-}
  125.  
  126. const
  127. SCnPingData = 'FtPack Ping.';
  128. ICMPDLL = 'icmp.dll';
  129.  
  130. type
  131.  
  132. //==============================================================================
  133. // 辅助过程 从icmp.dll导入的函数
  134. //==============================================================================
  135.  
  136. TIcmpCreateFile = function( ): THandle; stdcall;
  137.  
  138. TIcmpCloseHandle = function( IcmpHandle: THandle ): Boolean; stdcall;
  139.  
  140. TIcmpSendEcho = function( IcmpHandle: THandle;
  141. DestAddress: DWORD;
  142. RequestData: Pointer;
  143. RequestSize: Word;
  144. RequestOptions: PCnIPOptionInformation;
  145. ReplyBuffer: Pointer;
  146. ReplySize: DWord;
  147. TimeOut: DWord ): DWord; stdcall;
  148.  
  149. var
  150. IcmpCreateFile: TIcmpCreateFile = nil;
  151. IcmpCloseHandle: TIcmpCloseHandle = nil;
  152. IcmpSendEcho: TIcmpSendEcho = nil;
  153.  
  154. IcmpDllHandle: THandle = ;
  155.  
  156. procedure InitIcmpFunctions;
  157. begin
  158. IcmpDllHandle := LoadLibrary( ICMPDLL );
  159. if IcmpDllHandle <> then
  160. begin
  161. @IcmpCreateFile := GetProcAddress( IcmpDllHandle, 'IcmpCreateFile' );
  162. @IcmpCloseHandle := GetProcAddress( IcmpDllHandle, 'IcmpCloseHandle' );
  163. @IcmpSendEcho := GetProcAddress( IcmpDllHandle, 'IcmpSendEcho' );
  164. end;
  165. end;
  166.  
  167. procedure FreeIcmpFunctions;
  168. begin
  169. if IcmpDllHandle <> then
  170. FreeLibrary( IcmpDllHandle );
  171. end;
  172.  
  173. //==============================================================================
  174. // Ping 通讯类
  175. //==============================================================================
  176.  
  177. { TFtPing }
  178.  
  179. constructor TFtPing.Create( AOwner: TComponent );
  180. begin
  181. inherited Create( AOwner );
  182. FRemoteIP := '127.0.0.1';
  183. FTTL := ;
  184. FPingCount := ;
  185. FDelay := ;
  186. FTimeOut := ;
  187. FDataString := SCnPingData;
  188.  
  189. hICMP := IcmpCreateFile( ); // 取得DLL句柄
  190. if hICMP = INVALID_HANDLE_VALUE then
  191. begin
  192. raise Exception.Create( SICMPRunError );
  193. end;
  194. end;
  195.  
  196. destructor TFtPing.Destroy;
  197. begin
  198. if hICMP <> INVALID_HANDLE_VALUE then
  199. begin
  200. IcmpCloseHandle( hICMP );
  201. end;
  202. inherited Destroy;
  203. end;
  204.  
  205. procedure TFtPing.SetPingCount( const Value: Integer );
  206. begin
  207. if Value > then
  208. FPingCount := Value;
  209. end;
  210.  
  211. procedure TFtPing.SetRemoteIP( const Value: string );
  212. begin
  213. if FRemoteIP <> Value then
  214. begin
  215. FRemoteIP := Value;
  216. if SetIP( FRemoteIP, '', FIP ) then
  217. begin
  218. FRemoteHost := FIP.Host;
  219. FIPAddress := FIP.Address;
  220. end;
  221. end;
  222. end;
  223.  
  224. procedure TFtPing.SetRemoteHost( const Value: string );
  225. begin
  226. if FRemoteHost <> Value then
  227. begin
  228. // RemoteHost 更改的话,RemoteIP 自动清空
  229. FRemoteHost := Value;
  230. if SetIP( '', FRemoteHost, FIP ) then
  231. begin
  232. FRemoteIP := FIP.IP;
  233. FIPAddress := FIP.Address;
  234. end;
  235. end;
  236. end;
  237.  
  238. procedure TFtPing.SetTimeOut( const Value: DWord );
  239. begin
  240. FTimeOut := Value;
  241. end;
  242.  
  243. procedure TFtPing.SetTTL( const Value: Byte );
  244. begin
  245. FTTL := Value;
  246. end;
  247.  
  248. procedure TFtPing.SetDataString( const Value: string );
  249. begin
  250. FDataString := Value;
  251. end;
  252.  
  253. function TFtPing.GetDataString: string;
  254. begin
  255. if FDataString = '' then
  256. FDataString := SCnPingData;
  257. Result := FDataString;
  258. end;
  259.  
  260. function TFtPing.IsOnline: Boolean;
  261. var
  262. sReply: string;
  263. begin
  264. SetIP( RemoteIP, RemoteHost, FIP );
  265. Result := PingIP_Host( FIP, pointer( FDataString )^, Length( DataString ), sReply ) >= ;
  266. end;
  267.  
  268. function TFtPing.Ping( var aReply: string ): Boolean;
  269. var
  270. iCount, iResult: Integer;
  271. sReply: string;
  272. begin
  273. aReply := '';
  274. iResult := ;
  275. try
  276. SetIP( RemoteIP, RemoteHost, FIP );
  277. for iCount := to PingCount do
  278. begin
  279. iResult := PingIP_Host( FIP, Pointer( FDataString )^, Length( DataString ) * SizeOf( Char ), sReply );
  280. aReply := aReply + ## + sReply;
  281. if iResult < then
  282. Break;
  283.  
  284. if FDelay > then
  285. Sleep( FDelay );
  286. end;
  287. finally
  288. Result := iResult >= ;
  289. end;
  290. end;
  291.  
  292. function TFtPing.PingOnce( var aReply: string ): Boolean;
  293. begin
  294. SetIP( RemoteIP, RemoteHost, FIP );
  295. Result := PingIP_Host( FIP, pointer( FDataString )^, Length( DataString ), aReply ) >= ;
  296. end;
  297.  
  298. function TFtPing.PingOnce( const aIP: string; var aReply: string ): Boolean;
  299. begin
  300. SetIP( aIP, aIP, FIP );
  301. Result := PingIP_Host( FIP, pointer( FDataString )^, Length( DataString ), aReply ) >= ;
  302. end;
  303.  
  304. function TFtPing.PingFromBuffer( var Buffer; Count: Integer; var aReply: string ): Boolean;
  305. begin
  306. SetIP( RemoteIP, RemoteHost, FIP );
  307. Result := PingIP_Host( FIP, Buffer, Count, aReply ) >= ;
  308. end;
  309.  
  310. function TFtPing.PingIP_Host( const aIP: TIpInfo; const Data; Count: Cardinal; var aReply: string ): Integer;
  311. var
  312. IPOpt: TCnIPOptionInformation; // 发送数据结构
  313. pReqData, pRevData: PAnsiChar;
  314. pCIER: PCnIcmpEchoReply;
  315. begin
  316. Result := -;
  317. pReqData := nil;
  318.  
  319. if Count <= then
  320. begin
  321. aReply := GetReplyString( Result, aIP, nil );
  322. Exit;
  323. end;
  324. if aIP.Address = INADDR_NONE then
  325. begin
  326. Result := -;
  327. aReply := GetReplyString( Result, aIP, nil );
  328. Exit;
  329. end;
  330.  
  331. GetMem( pCIER, SizeOf( TCnICMPEchoReply ) + Count );
  332. GetMem( pRevData, Count );
  333. try
  334. FillChar( pCIER^, SizeOf( TCnICMPEchoReply ) + Count, ); // 初始化接收数据结构
  335. pCIER^.Data := pRevData;
  336. GetMem( pReqData, Count );
  337. Move( Data, pReqData^, Count ); // 准备发送的数据
  338. FillChar( IPOpt, Sizeof( IPOpt ), ); // 初始化发送数据结构
  339. IPOpt.TTL := FTTL;
  340.  
  341. try //Ping开始
  342. if WSAStartup( MAKEWORD( , ), FWSAData ) <> then
  343. raise Exception.Create( SInitFailed );
  344. if IcmpSendEcho( hICMP, //dll handle
  345. aIP.Address, //target
  346. pReqData, //data
  347. Count, //data length
  348. @IPOpt, //addree of ping option
  349. pCIER,
  350. SizeOf( TCnICMPEchoReply ) + Count, //pack size
  351. FTimeOut //timeout value
  352. ) <> then
  353. begin
  354. Result := ; // Ping正常返回
  355. if Assigned( FOnReceived ) then
  356. FOnReceived( Self, aIP.IP, aIP.Host, IPOpt.TTL, IPOpt.TOS );
  357. end
  358. else
  359. begin
  360. Result := -; // 没有响应
  361. if Assigned( FOnError ) then
  362. FOnError( Self, aIP.IP, aIP.Host, IPOpt.TTL, IPOpt.TOS, SNoResponse );
  363. end;
  364. except
  365. on E: Exception do
  366. begin
  367. Result := -; // 发生错误
  368. if Assigned( FOnError ) then
  369. FOnError( Self, aIP.IP, aIP.Host, IPOpt.TTL, IPOpt.TOS, E.Message );
  370. end;
  371. end;
  372. finally
  373. WSACleanUP;
  374. aReply := GetReplyString( Result, aIP, pCIER );
  375. if pRevData <> nil then
  376. begin
  377. FreeMem( pRevData ); // 释放内存
  378. pCIER.Data := nil;
  379. end;
  380. if pReqData <> nil then
  381. FreeMem( pReqData ); //释放内存
  382. FreeMem( pCIER ); //释放内存
  383. end;
  384. end;
  385.  
  386. function TFtPing.GetReplyString( aResult: Integer; aIP: TIpInfo;
  387. pIPE: PCnIcmpEchoReply ): string;
  388. var
  389. sHost: string;
  390. begin
  391. Result := SInvalidAddr;
  392. case aResult of
  393. -: Result := SICMPRunError;
  394. -: Result := SInvalidAddr;
  395. -: Result := Format( SNoResponse, [ RemoteHost ] );
  396. else
  397. if pIPE <> nil then
  398. begin
  399. sHost := aIP.IP;
  400. if aIP.Host <> '' then
  401. sHost := aIP.Host + ': ' + sHost;
  402. Result := ( Format( SPingResultString, [ sHost, pIPE^.DataSize, pIPE^.RTT,
  403. pIPE^.Options.TTL ] ) );
  404. end;
  405. end;
  406. end;
  407.  
  408. function TFtPing.GetIPByName( const aName: string;
  409. var aIP: string ): Boolean;
  410. var
  411. pHost: PHostEnt;
  412. FWSAData: TWSAData;
  413. sName: array[ .. ] of AnsiChar;
  414. begin
  415. Result := False;
  416. // StrPCopy(sName, {$IFDEF DELPHI12_UP}AnsiString{$ENDIF}(aName));
  417. StrPCopy( sName, AnsiString( aName ) );
  418. aIP := '';
  419. if aName = '' then
  420. Exit;
  421.  
  422. WSAStartup( $, FWSAData );
  423. try
  424. pHost := GetHostByName( @sName );
  425. Result := pHost <> nil;
  426. if Result then
  427. // aIP := {$IFDEF DELPHI12_UP}string{$ENDIF}(inet_ntoa(PInAddr(pHost^.h_addr_list^)^));
  428. aIP := string( inet_ntoa( PInAddr( pHost^.h_addr_list^ )^ ) );
  429. finally
  430. WSACleanup;
  431. end;
  432. end;
  433.  
  434. function TFtPing.SetIP( aIPAddr, aHost: string; var aIP: TIpInfo ): Boolean;
  435. var
  436. pIPAddr: PAnsiChar;
  437. begin
  438. Result := False;
  439. aIP.Address := INADDR_NONE;
  440. aIP.IP := aIPAddr;
  441. aIP.Host := aHost;
  442. if aIP.IP = '' then
  443. begin
  444. if ( aIP.Host = '' ) or ( not GetIPByName( aIP.Host, aIP.IP ) ) then
  445. Exit;
  446. end;
  447.  
  448. GetMem( pIPAddr, Length( aIP.IP ) + );
  449. try
  450. ZeroMemory( pIPAddr, Length( aIP.IP ) + );
  451. // StrPCopy(pIPAddr, {$IFDEF DELPHI12_UP}AnsiString{$ENDIF}(aIP.IP));
  452. StrPCopy( pIPAddr, AnsiString( aIP.IP ) );
  453. aIP.Address := inet_addr( PAnsiChar( pIPAddr ) ); // IP转换成无点整型
  454. finally
  455. FreeMem( pIPAddr ); // 释放申请的动态内存
  456. end;
  457. Result := aIP.Address <> INADDR_NONE;
  458. end;
  459.  
  460. initialization
  461. InitIcmpFunctions;
  462.  
  463. finalization
  464. FreeIcmpFunctions;
  465.  
  466. end.
  467.  
  468. {
  469. 调用方法
  470. procedure TForm1.Button1Click( Sender: TObject );
  471. var
  472. FtPing: TFtPing;
  473. aReply: string;
  474. begin
  475. FtPing := TFtPing.Create( nil );
  476. try
  477. FtPing.RemoteIP := Edit1.Text;
  478. if FtPing.Ping( aReply ) then
  479. begin
  480. Memo1.Lines.Add( '网络畅通!' )
  481. end
  482. else
  483. begin
  484. Memo1.Lines.Add( '网络异常~~>|<~~' )
  485. end;
  486. finally
  487. FtPing.Free;
  488. end;
  489. end;
  490.  
  491. }

正则取匹配IP地址

  1. Reg:=TPerlRegEx.Create;
  2. Reg.Subject:=pos.ServerUrl;
  3. Reg.RegEx:='((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)';
  4.  
  5. if reg.Match then
  6. IP:=Reg.MatchedText
  7. else
  8. //TODO 没有获取到IP地址

Delphi 实现Ping命令的更多相关文章

  1. [delphi]运行cmd命令,并取得输出字符

     http://blog.csdn.net/nerdy/article/details/8969189 [delphi]运行cmd命令,并取得输出字符 标签: delphiCMD命令 2013-05- ...

  2. [转]Delphi执行CMD命令

    今天看到有人在问用代码执行CMD命令的问题,就总结一下用法,也算做个备忘. Delphi中,执行命令或者运行一个程序有2个函数,一个是winexec,一个是shellexecute.这两个大家应该都见 ...

  3. Docker的ubuntu镜像安装的容器无ifconfig和ping命令的解决

    Docker的Ubuntu镜像安装的容器无ifconfig命令和ping命令 解决: apt-get update apt install net-tools       # ifconfig apt ...

  4. windows 环境和linux环境下 ping命令的区别:

    Ping 是Windows自带的一个DOS命令.利用它可以检查网络是否能够连通,用好它可以很好地帮助我们分析判定网络故障.该命令可以加许多参数使用,键入Ping按回车即可看到详细说明.Ping 命令可 ...

  5. ping命令执行过程详解

    [TOC] ping命令执行过程详解 机器A ping 机器B 同一网段 ping通知系统建立一个固定格式的ICMP请求数据包 ICMP协议打包这个数据包和机器B的IP地址转交给IP协议层(一组后台运 ...

  6. ping命令脚本实现显示网络状态、学生姓名、学号

    #!/bin/bash a=. ####定义一个固定变量 h=(wanghao xieyunshen 刘桃) ####定义数组 ..} ####for循环,后面的in是条件即从多少循环到多少 do # ...

  7. [小菜随笔]python tkinter实现简单的ping命令

    本文主要是介绍python图形界面上的按键与实际功能的对接,其实编程掌握了基础之后的学习应该都是靠自己去挖掘其他的 在网上发现多半教程都是2的,故本文使用的是python3.5,其实也没什么区别,就有 ...

  8. cmd中用PING命令时,出现'Ping' 不是内部或外部命令 解决方案

    在cmd中用PING命令时,出现'Ping' 不是内部或外部命令,也不是可运行的程序或批处理文件.先了解一下内容:1.可执行文件.命令文件和批处理文件以.exe或者.com或者.bat为扩展名的文件分 ...

  9. ping命令

    ping命令能够用于判断一个主机是否可达或者是否存活.它的工作原理就像潜水艇的探测原理一样.该命令通过向目标计算机发送一个数据包,请求目标计算机回送该数据包以表明自己还存活着.同时该命令还能够知道数据 ...

随机推荐

  1. 补码一位乘法 Booth算法 Java简易实现

    本文链接:https://www.cnblogs.com/xiaohu12138/p/11955619.html. 转载,请说明出处. 本程序为简易实现补码一位乘法,若代码中存在错误,可指出,本人会不 ...

  2. thinkphp5中的raw的作用

    模板中输出变量 默认不展示HTMl 使用raw将其中的中的HTMl内容展示出来 <div class="content"> <div class="co ...

  3. Django-djangorestframework-请求模块-获取请求参数

    目录 请求模块 源码分析 正式使用 总结 请求模块 主要是分析 drf 二次封装后的 request 对象 以及怎么拿到请求传递过来的数据(url 拼接的数据,数据包传过来的数据) 源码分析 源码查看 ...

  4. Web API 自动生成接口文档

    1.添加NuGet程序包 Microsoft ASP.NET Web API 2.2 Help Page      (这是微软官方的) A Simple Test Client for ASP.NET ...

  5. Windows 编程 键盘

    键盘对于大家来说可能再也熟悉不过了,它和鼠标是现在最常用的电脑输入设备.虽然在现在的图形界面操作系统下使用鼠标比使用键盘更方便.更广泛,但是鼠标还是一时半会儿取代不了它的老前辈——键盘的地位,尤其是在 ...

  6. LINQ 多条件join on

    var  tmp = from a in DT1.AsEnumerable() join b in DT2.AsEnumerable() on new { bm = a.Field<string ...

  7. Abp 聚合测试

    Abp 官网开始的教程例子,是IRpositoty<entity> 直接出现在应用层.但是如果是一个聚合根也会这样吗?  那么聚合根是访问仓储的最小单元,要通过聚合根来操作业务,就是实体, ...

  8. element ui的照片墙 默认显示照片

    参考地址: element ui的照片墙 默认显示照片 照片显示的数据格式是:[{name: '', url: ''}],:file-list=""默认显示的图片 实际项目开发中需 ...

  9. You are using the runtime-only build of Vue where the template compiler is not available.

    使用vue-cli搭建的项目,启动报错 You are using the runtime-only build of Vue where the template compiler is not a ...

  10. 文件 file open函数的打开及 函数的调用

    文件 mode 模式字符的含义 字符 含义 'r' 以只读方式打开(默认) 'w' 以只写方式打开,删除原有文件内容(如果文件不存在,则创建该文件并以只写方式打开) 'x' 创建一个新文件, 并以写模 ...