在 Windows 95/NT 環境下,標準 Winsock API 未直接提供 ICMP Ping 功能。Microsoft 直到 Winsock 2.0 仍未內建解決方案,開發者需自行呼叫 ICMP DLL 實作。
本文提供一個 CIcmpEcho 類別(繼承自 CSocket),封裝 ICMP.DLL 核心函數,提供四個公用方法:
ResolveIP(CString strIP) — 將 IP 字串轉為網路位序位址ResolveName(CString strHostName) — 透過 DNS/WINS 解析主機名稱GetIP(ULONG ulIP) — 將數值位址轉回點分十進制字串PingHost(ULONG ulIP, int iPingTimeout) — 執行 Ping 並返回往返時間 (ms)class CIcmpEcho : public CSocket {
public:
CIcmpEcho(); virtual ~CIcmpEcho();
ULONG ResolveIP(CString strIP);
ULONG ResolveName(CString strHostName);
DWORD PingHost(ULONG ulIP, int iPingTimeout);
CString GetIP(ULONG ulIP);
protected:
// ClassWizard 生成的虛擬函數覆寫
};
DWORD CIcmpEcho::PingHost(ULONG ulIP, int iPingTimeout) {
HANDLE hIcmp = IcmpCreateFile();
char reply[sizeof(ICMP_ECHO_REPLY) + 8];
PICMP_ECHO_REPLY pReply = (PICMP_ECHO_REPLY)reply;
pReply->RoundTripTime = 0xFFFFFFFF;
IcmpSendEcho(hIcmp, ulIP, NULL, 0, NULL, reply, sizeof(reply), iPingTimeout);
IcmpCloseHandle(hIcmp);
return pReply->RoundTripTime;
}
其他輔助函數使用 inet_addr、gethostbyname、inet_ntoa 完成位址轉換與解析。
ICMPAPI.H、ICMPAPI.CPP、ICMP.LIB、IPEXPORT.H、IPEXPORT.CPP(可從 MSDN 取得)。CIcmpEcho,呼叫 ResolveName 或 ResolveIP 取得位址,再呼叫 PingHost 執行偵測。0xFFFFFFFF 表示逾時或失敗。Icmp6SendEcho2 等新 API。封裝 ICMP DLL 為 MFC 應用程式提供了輕量級 Ping 能力,避免依賴外部 ping.exe 解析輸出,適合內建網路診斷功能的桌面應用。