⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ppingdlg.cpp

📁 ping的小程序
💻 CPP
字号:
// ppingDlg.cpp : implementation file
//

#include "stdafx.h"
#include "pping.h"
#include "ppingDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define ICMP_ECHO 8     //ICMP请求响应
#define ICMP_REPLY 0    //ICMP响应
#define BUFSIZE 1024    //缓冲区的大小
#define TIMES 20        //默认ping的次数
#define TIMEOUT 100    //最长的等待时间为一秒

/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
//求ICMP头校验和
WORD CheckSum(WORD *buffer,int size)
{

WORD cksum=0;
	while(size>1)
	{	
	
	cksum+=*buffer++;
	size-=sizeof(WORD);
	}
	if(size)
		cksum+=*(UCHAR*)buffer;
	cksum=(cksum>>16)+(cksum&0xffff);
	cksum+=(cksum>>16);
	return (~cksum);

}
////////////////
BOOL PingOnce(SOCKET hsock,CPpingDlg* pDlg)
{
char recvByte[BUFSIZE];
char sendByte[BUFSIZE];
int sendBytesCount;
int recvBytesCount;
int sendsize;
int recvsize;
int IPHeaderSize;
DWORD* ptime;
DWORD sendTime,recvTime;
struct IPHeader* pIP;
struct ICMPHeader* pICMP;
SOCKADDR_IN s_sockaddr;
SOCKADDR_IN d_sockaddr;
CString Info;
d_sockaddr.sin_family=AF_INET;
d_sockaddr.sin_addr=*(LPIN_ADDR)*(pDlg->m_lpHostEnt->h_addr_list);
pICMP=(ICMPHeader*)sendByte;
pICMP->type=ICMP_ECHO;
pICMP->code=0;
pICMP->ID=(WORD)GetCurrentProcessId();
pICMP->seq=0;
pICMP->checksum=0;
ptime=(DWORD*)(sendByte+sizeof(ICMPHeader));
sendTime=GetTickCount();//取发送的时刻
*ptime=sendTime;
sendsize=sizeof(ICMPHeader)+sizeof(DWORD);
//求ICMP的校验和
pICMP->checksum=CheckSum((WORD*)pICMP,sendsize);
// 用socket发送数据报
sendBytesCount=sendto(hsock,(LPSTR)pICMP,sendsize,0,
					  (LPSOCKADDR)&d_sockaddr,sizeof(d_sockaddr));
//判断传送是否成功
	if(sendBytesCount==SOCKET_ERROR)
	{
		if(WSAGetLastError()==WSAETIMEDOUT)
			pDlg->m_ListInfo.InsertString(pDlg->m_ListInfo.GetCount(),"Request time out ...");
		return FALSE;	
	}
	if(sendBytesCount<sendsize)
		return FALSE;
	recvsize=sizeof(s_sockaddr);
	//接收响应数据报
	int timeout=1000;
	setsockopt(hsock,SOL_SOCKET,SO_RCVTIMEO,(char*)&timeout,
		sizeof(timeout));
	try
	{
	recvBytesCount=recvfrom(hsock,recvByte,BUFSIZE,0,(LPSOCKADDR)&s_sockaddr,&recvsize);
	}
	catch(...)
	{pDlg->m_ListInfo.InsertString(pDlg->m_ListInfo.GetCount(),"request time out...");}
	//取接收到数据报的时刻
	
	
	recvTime=GetTickCount();
	//判断接收过程之否有错
	if(recvBytesCount==SOCKET_ERROR)
	{
	if(WSAGetLastError()==WSAETIMEDOUT)
		pDlg->m_ListInfo.InsertString(pDlg->m_ListInfo.GetCount(),"request time out...");
	return FALSE;
	}
	pIP=(IPHeader*)recvByte;
	//取IP头的长度
	IPHeaderSize=(BYTE)((pIP->verlen<<4)>>2);
	if(recvBytesCount<IPHeaderSize+(int)sizeof(ICMPHeader))
		return FALSE;
	pICMP=(ICMPHeader*)(recvByte+IPHeaderSize);
	//判断是否是响应的数据报
	if(pICMP->ID!=GetCurrentProcessId())
		return FALSE;
	//如果数据接收成功,则显示数据
	Info.Format(":Bytes: %d time %d ms TTL: %d",recvBytesCount,
		recvTime-sendTime,(UINT)pIP->TTL);
	Info=inet_ntoa(*(LPIN_ADDR)*(pDlg->m_lpHostEnt->h_addr_list))+Info;
	Info="Reply from"+Info;
	pDlg->m_ListInfo.InsertString(pDlg->m_ListInfo.GetCount(),Info);
	return TRUE;

}

DWORD WINAPI DoPing(LPVOID lpparameter)
{
LPINFO temp=(LPINFO)lpparameter;
UINT times=0;
	while((temp->flag)&&(times<temp->times))
	{
	PingOnce(temp->hsock,(CPpingDlg*)(temp->pdlg));
	times++;
	}
	return 0;
}


/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CAboutDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:
	//{{AFX_MSG(CAboutDlg)
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
		// No message handlers
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CPpingDlg dialog

CPpingDlg::CPpingDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CPpingDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CPpingDlg)
	m_Times = 20;
	m_IPAddr = _T("");
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CPpingDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CPpingDlg)
	DDX_Control(pDX, IDC_LIST_INFO, m_ListInfo);
	DDX_Text(pDX, IDC_EDIT_TIMES, m_Times);
	DDX_Text(pDX, IDC_EDIT_IP, m_IPAddr);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CPpingDlg, CDialog)
	//{{AFX_MSG_MAP(CPpingDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_BUTTON_PING, OnButtonPing)
	ON_BN_CLICKED(IDC_BUTTON_STOP, OnButtonStop)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CPpingDlg message handlers

BOOL CPpingDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Add "About..." menu item to system menu.

	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	
	// TODO: Add extra initialization here
	
	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CPpingDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CPpingDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CPpingDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

void CPpingDlg::OnButtonPing() 
{
	// TODO: Add your control notification handler code here
	
	// TODO: Add your control notification handler code here
	CString strIP;
	protoent* lpproto;
	int proto;
	SOCKET hsock;
	int returncode;
	int timeout;
	CString Errmsg;
	DWORD ThreadID;
	DWORD code;
	//删除m_ListInfo中的所有信息
	while(m_ListInfo.GetCount()!=0)
	m_ListInfo.DeleteString(m_ListInfo.GetTopIndex());
	//取得m_lpHostEnt
	if(!GetHostEnt())
	{
		Errmsg.Format("There is no this host computer!");
		m_ListInfo.InsertString(m_ListInfo.GetCount(),(LPCTSTR)Errmsg);
		return ;
	}
	//取得主机的地址
	strIP=inet_ntoa(*(LPIN_ADDR)*(m_lpHostEnt->h_addr_list));
	m_ListInfo.AddString("Ping"+strIP);
	m_ListInfo.InsertString(m_ListInfo.GetCount(),"Connecting...");
	//取得协议的类型
	lpproto=getprotobyname("icmp");
	if(lpproto==NULL)
	 proto=IPPROTO_ICMP;
	else
	 proto=lpproto->p_proto;
	//生成Socket句柄
	//	hsock=WSASocket(AF_INET,SOCK_RAW,proto,NULL,0,0);//必须用WSA_FLAG_OVERLAPPED,否则设置的
	//套接字选项RCVTIMEO不起作用,并且无限制等待
	hsock=WSASocket(AF_INET,SOCK_RAW,proto,NULL,0,WSA_FLAG_OVERLAPPED);
		if(hsock==INVALID_SOCKET)
		{
		Errmsg.Format("Socket error");
		m_ListInfo.InsertString(m_ListInfo.GetCount(),(LPCTSTR)Errmsg);
		return;
		}
	timeout=TIMEOUT;
	returncode=setsockopt(hsock,SOL_SOCKET,SO_RCVTIMEO,(char*)&timeout,
		sizeof(timeout));
		if(returncode==SOCKET_ERROR)
		{
		Errmsg.Format("Socket error");
		m_ListInfo.InsertString(m_ListInfo.GetCount(),(LPCTSTR)Errmsg);
		return;
		}
		timeout=TIMEOUT;
	returncode=setsockopt(hsock,SOL_SOCKET,SO_SNDTIMEO,(char*)&timeout,
		sizeof(timeout));
		if(returncode==SOCKET_ERROR)
		{
		Errmsg.Format("Socket error");
		m_ListInfo.InsertString(m_ListInfo.GetCount(),(LPCTSTR)Errmsg);
		return;
		}

		//对m_Info进行赋值
		m_Info.flag=TRUE;
		m_Info.hsock=hsock;
		m_Info.pdlg=this;
		//取得用户设定的次数
		UpdateData(TRUE);
		if(m_Times<=0)
		
		m_Info.times=m_Times=TIMES;
		else
		m_Info.times=m_Times;
		UpdateData(FALSE);//对数据进行回显
		//创建ping的线程
	if(!GetExitCodeThread(m_hThread,&code)||(code!=STILL_ACTIVE))
		m_hThread=CreateThread(NULL,0,DoPing,&m_Info,0,&ThreadID);
	if(m_hThread==NULL)
		MessageBox("Create thread ping failed!");
	
}

void CPpingDlg::OnButtonStop() 
{
	// TODO: Add your control notification handler code here
		DWORD code;
	//设置停止标志
	m_Info.flag=FALSE;
	Sleep(TIMEOUT);
	//如果线程还没有停止,则强制它停止//INVALID_SOCKET//FD_ISSET
	if(GetExitCodeThread(m_hThread,&code))
		if(code==STILL_ACTIVE)
		{
		TerminateThread(m_hThread,0);
		CloseHandle(m_hThread);
		}

	
}

void CPpingDlg::OnOK() 
{
	// TODO: Add extra validation here
	OnButtonStop();

	
	CDialog::OnOK();
}

BOOL CPpingDlg::GetHostEnt()
{
	UpdateData(TRUE);
	//如果用户输入的数据是主机名
	m_lpHostEnt=gethostbyname((LPCSTR)m_IPAddr);
	if(m_lpHostEnt==NULL)
	{
	DWORD dwIP;
	dwIP=inet_addr((LPCSTR)m_IPAddr);
	//如果用户输入是IP地址
	m_lpHostEnt=gethostbyaddr((LPSTR)&dwIP,4,AF_INET);
	if(m_lpHostEnt==NULL)
		return FALSE;
	}
	return TRUE;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -