IP Helper 可能需要WDK支持, 我本机装了WDK, 没试过不用会怎样.
由于IcmpSendEcho2Ex()回调的形式似乎与我的WDK有所冲突, 所以这里只演示阻塞模式. Event应该不受影响.
Demo下载地址: http://download.csdn.net/detail/ren0065/8388105
主要代码:
void CPingTest1Dlg::OnBnClickedBtnPing()
{
// TODO: 在此添加控件通知处理程序代码
UpdateData(TRUE);
HANDLE h_icmp = IcmpCreateFile();
IPAddr ip_source = inet_addr(cs_source_ip_);
IPAddr ip_destination = inet_addr(cs_destination_ip_);
WORD w_request_data_size = atoi(cs_request_size_);
LPVOID p_request_data = calloc(1, w_request_data_size);
PIP_OPTION_INFORMATION p_option_info = NULL;
LPVOID p_reply_data = calloc(1, sizeof(ICMP_ECHO_REPLY) + 8 + w_request_data_size);
DWORD dw_reply_data_size = sizeof(ICMP_ECHO_REPLY) + 8 + w_request_data_size;
DWORD dw_timeout = atoi(cs_timeout_);
DWORD dw_result = IcmpSendEcho2Ex(
h_icmp
, NULL
, NULL
, NULL
, ip_source
, ip_destination
, p_request_data
, w_request_data_size
, p_option_info
, p_reply_data
, dw_reply_data_size
, dw_timeout);
free(p_request_data);
cs_output_.Empty();
if (dw_result == 0)
{
DWORD dw_error = GetLastError();
CString cs_error_msg;
switch (dw_error)
{
case ERROR_INVALID_PARAMETER:
cs_error_msg = "无效参数. 当IcmpHandle是一个无效handle或ReplySize的值小于ICMP_ECHO_REPLY或ICMP_ECHO_REPLY32时会返回该错误.";
break;
case ERROR_IO_PENDING:
cs_error_msg = "异步处理正在进行中.调用IcmpSendEcho2Ex异步模式成功时会返回该值, 不是错误.";
break;
case ERROR_NOT_ENOUGH_MEMORY:
cs_error_msg = "内存不足";
break;
case ERROR_NOT_SUPPORTED:
cs_error_msg = "不支持该请求.如果本地计算机没有IPv4协议栈将返回该错误.";
break;
case IP_BUF_TOO_SMALL:
cs_error_msg = "ReplySize指定的太小.";
break;
default:
{
HLOCAL hLocal = NULL;
DWORD dwErr = GetLastError();
DWORD systemLocale = MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL);
DWORD fOK = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_ALLOCATE_BUFFER,
NULL, dwErr, systemLocale, (LPTSTR)&hLocal, 0, NULL);
cs_error_msg = (LPCTSTR)LocalLock(hLocal);
break;
}
}
cs_output_ = cs_error_msg;
}
else
{
CString cs_buffer;
PICMP_ECHO_REPLY pEchoReply = (PICMP_ECHO_REPLY)p_reply_data;
struct in_addr ReplyAddr;
ReplyAddr.S_un.S_addr = pEchoReply->Address;
cs_buffer.Format("Sent icmp message from %s to %s\r\n", cs_source_ip_, cs_destination_ip_);
cs_output_ += cs_buffer;
if (dw_result > 1)
{
cs_buffer.Format("Received %ld icmp message responses\r\n", dw_result);
cs_output_ += cs_buffer;
cs_buffer.Format("Information from the first response:\r\n");
cs_output_ += cs_buffer;
}
else
{
cs_buffer.Format("Received %ld icmp message response\r\n", dw_result);
cs_output_ += cs_buffer;
cs_buffer.Format("Information from this response:\r\n");
cs_output_ += cs_buffer;
}
cs_buffer.Format("Received from %s\r\n", inet_ntoa(ReplyAddr));
cs_output_ += cs_buffer;
cs_buffer.Format("Status = %ld ", pEchoReply->Status);
cs_output_ += cs_buffer;
if (pEchoReply->Status != IP_SUCCESS)
{
DWORD dw_status_err_msg_size = 1024;
PWSTR cw_str_error = (PWSTR)calloc(1, dw_status_err_msg_size);
GetIpErrorString(pEchoReply->Status, cw_str_error, &dw_status_err_msg_size);
cs_output_ = WS2S(cw_str_error).c_str();
free(cw_str_error);
}
else
{
cs_buffer.Format("(Successful)\r\n");
cs_output_ += cs_buffer;
cs_buffer.Format("RTT: %d\r\n", pEchoReply->RoundTripTime);
cs_output_ += cs_buffer;
cs_buffer.Format("SIZE: %d\r\n", pEchoReply->DataSize);
cs_output_ += cs_buffer;
cs_buffer.Format("TTL: %d\r\n", pEchoReply->Options.Ttl);
cs_output_ += cs_buffer;
}
}
UpdateData(FALSE);
free(p_reply_data);
IcmpCloseHandle(h_icmp);
}