首頁  >  文章  >  資料庫  >  自制Ping(3) IcmpSendEcho2Ex Demo

自制Ping(3) IcmpSendEcho2Ex Demo

WBOY
WBOY原創
2016-06-07 15:42:441555瀏覽

IP Helper 可能需要WDK支持, 我本机装了WDK, 没试过不用会怎样. 由于IcmpSendEcho2Ex()回调的形式乎与我的WDK有所冲突, 所以这里只演示阻塞模式. Event应该不受影响. Demo下载地址: http://download.csdn.net/detail/ren0065/8388105 主要代码: void CPingTe

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);
}


陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn