c++ ping 功能实现(mfc)
现在我们将代码移植到我们的mfc中,定义编辑款edit3为域名输入,IDC_IPADDRESS2为解析IP地址;Button1为启动测试控制键。
为button1添加bn_clicked事件回调函数:
设置button1文本context内容:
CButton*pbutton = (CButton*)this->GetDlgItem(IDC_BUTTON1); //set button context SetDlgItemText(IDC_BUTTON1, _T("PingRunning")); //disable button during ping net pbutton->EnableWindow(FALSE);
因为我们在执行过程中,需要一定的时间,所以在此过程中我们禁止用户再次按下button1,将button1设置为禁用状态 pbutton->EnableWindow(FALSE);
接着我们读取编辑框内容,即读取域名,并将其解析为IP地址,分配给IDC_IPADDRESS2
UpdateData(true); //get domain from edit3 dialog GetDlgItem(IDC_EDIT3)->GetWindowText(str); strcpy_s(szDomain, str); //get ip address from domain BOOL bResult = objPing.GetIpByDomainName(szDomain, szIp0, &nCount);
将ip地址提取到cstring类变量,然后将该变量转换成DWORD类型,用于分配于IDC_IPADDRESS2控件:
szDestIP = &szIp0[0][0]; DWORD dwIP = ntohl(inet_addr(szDestIP)); CIPAddressCtrl*pIP = (CIPAddressCtrl*)this->GetDlgItem(IDC_IPADDRESS2); pIP->SetAddress(dwIP);
inet_addr()函数的功能是将一个点分十进制的IP转换成一个长整数型数
ntohl()函数是是将一个无符号长整形数从网络字节顺序转换为主机字节顺序,返回一个以主机字节顺序表达的数。
这里是先将ip地址转成long int类型,之后将其转成主机字节,将其分配给IDC_IPADDRESS2
总结源码:
// myPingDlg.cpp : implementation file // #include "stdafx.h" #include "MicrohardTest.h" #include "myPingDlg.h" #include "afxdialogex.h" //user #include "MicrohardTestDlg.h" #include "Source.h" #include <winsock2.h> #include <stdio.h> #include <string.h> // myPingDlg dialog IMPLEMENT_DYNAMIC(myPingDlg, CDialogEx) myPingDlg::myPingDlg(CWnd* pParent /*=NULL*/) : CDialogEx(myPingDlg::IDD, pParent) , m_edit1_ping(_T("")) , m_edit2_web(_T("www.baidu.com")) { } myPingDlg::~myPingDlg() { } void myPingDlg::DoDataExchange(CDataExchange* pDX) { CDialogEx::DoDataExchange(pDX); DDX_Text(pDX, IDC_EDIT1, m_edit1_ping); DDX_Text(pDX, IDC_EDIT3, m_edit2_web); } BEGIN_MESSAGE_MAP(myPingDlg, CDialogEx) ON_BN_CLICKED(IDC_BUTTON3, &myPingDlg::OnBn3ClickedReturn) ON_BN_CLICKED(IDC_BUTTON1, &myPingDlg::OnBn1ClickedSend) ON_BN_CLICKED(IDC_BUTTON2, &myPingDlg::OnBn2ClickedClear) END_MESSAGE_MAP() // myPingDlg message handlers void myPingDlg::OnBn3ClickedReturn() { // TODO: Add your control notification handler code here myPingDlg::OnOK(); CMicrohardTestDlg mdlg; mdlg.DoModal(); } void myPingDlg::OnBn1ClickedSend() { // TODO: Add your control notification handler code here int nCount = 0; int def_package_cnt; char *szDestIP; char szIp0[100][100]; CString str; CString str_ip; CPing objPing; PingReply reply; char szDomain[256] = { 0 }; CButton*pbutton = (CButton*)this->GetDlgItem(IDC_BUTTON1); //set button context SetDlgItemText(IDC_BUTTON1, _T("PingRunning")); //disable button during ping net pbutton->EnableWindow(FALSE); UpdateData(true); //get domain from edit3 dialog GetDlgItem(IDC_EDIT3)->GetWindowText(str); strcpy_s(szDomain, str); //get ip address from domain BOOL bResult = objPing.GetIpByDomainName(szDomain, szIp0, &nCount); if (bResult == TRUE) { szDestIP = &szIp0[0][0]; DWORD dwIP = ntohl(inet_addr(szDestIP)); CIPAddressCtrl*pIP = (CIPAddressCtrl*)this->GetDlgItem(IDC_IPADDRESS2); pIP->SetAddress(dwIP); if (nCount == 0) { m_edit1_ping = _T("Failed! Domain is inviald."); } else { str_ip = szDestIP; str = _T("Ping address:") + str_ip + _T(" with 32 packages of data:\r\n"); m_edit1_ping = str; for (def_package_cnt = 0; def_package_cnt < DEF_PACKET_SIZE; def_package_cnt++) { bResult = objPing.Ping(szDestIP, &reply); if (bResult == TRUE) { str.Format(_T("Reply from : bytes=%d time=%ldms TTL=%ld\r\n"), reply.m_dwBytes, reply.m_dwRoundTripTime, reply.m_dwTTL); //Insert the IP address behind "from " str.Insert(11,str_ip); m_edit1_ping += str; } else { str.Format(_T("Failed: Ping did not response at %d package.\r\n"), def_package_cnt + 1); m_edit1_ping += str; } } } } else { m_edit1_ping = _T("WSA Startup failed!"); } UpdateData(FALSE); SetDlgItemText(IDC_BUTTON1, _T("PingRetry")); pbutton->EnableWindow(TRUE); } void myPingDlg::OnBn2ClickedClear() { // TODO: Add your control notification handler code here UpdateData(TRUE); if (m_edit1_ping.IsEmpty()==false) { m_edit1_ping = _T(""); UpdateData(FALSE); } }
谢谢,后续我们再将处理过程用一个线程来处理,避免程序阻塞。
End.