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

📄 ping.cpp

📁 一个MFC编写的PING程序
💻 CPP
字号:
#include "stdafx.h"
#include "ThreadInfo.h"

u_short in_cksum(u_short *addr, int len)
{
	register int nleft = len;
	register u_short *w = addr;
	register u_short answer;
	register int sum = 0;

	/*
	 *  Our algorithm is simple, using a 32 bit accumulator (sum),
	 *  we add sequential 16 bit words to it, and at the end, fold
	 *  back all the carry bits from the top 16 bits into the lower
	 *  16 bits.
	 */
	while( nleft > 1 )  {
		sum += *w++;
		nleft -= 2;
	}

	/* mop up an odd byte, if necessary */
	if( nleft == 1 ) {
		u_short	u = 0;

		*(u_char *)(&u) = *(u_char *)w ;
		sum += u;
	}

	/*
	 * add back carry outs from top 16 bits to low 16 bits
	 */
	sum = (sum >> 16) + (sum & 0xffff);	/* add hi 16 to low 16 */
	sum += (sum >> 16);			/* add carry */
	answer = ~sum;				/* truncate to 16 bits */
	return (answer);
}

int SendEchoRequest(SOCKET s, LPSOCKADDR_IN lpstToAddr)
{
	static ECHOREQUEST echoReq;
	static nId = 1;
	static nSeq = 1;
	int nRet;

	// Fill in echo request
	echoReq.icmpHdr.Type		= ICMP_ECHOREQ;
	echoReq.icmpHdr.Code		= 0;
	echoReq.icmpHdr.Checksum	= 0;
	echoReq.icmpHdr.ID			= nId++;
	echoReq.icmpHdr.Seq			= nSeq++;

	// Fill in some data to send
	for (nRet = 0; nRet < REQ_DATASIZE; nRet++)
		echoReq.cData[nRet] = ' '+nRet;

	// Save tick count when sent
	echoReq.dwTime				= GetTickCount();

	// Put data in packet and compute checksum
	echoReq.icmpHdr.Checksum = in_cksum((u_short *)&echoReq, sizeof(ECHOREQUEST));

	// Send the echo request  								  
	nRet = sendto(s,						/* socket */
				 (LPSTR)&echoReq,			/* buffer */
				 sizeof(ECHOREQUEST),
				 0,							/* flags */
				 (LPSOCKADDR)lpstToAddr, /* destination */
				 sizeof(SOCKADDR_IN));   /* address length */

	return (nRet);
}

int WaitForEchoReply(SOCKET s)
{
	struct timeval Timeout;
	fd_set readfds;

	readfds.fd_count = 1;
	readfds.fd_array[0] = s;
	Timeout.tv_sec = 1;
    Timeout.tv_usec = 0;
	return(select(1, &readfds, NULL, NULL, &Timeout));
}

DWORD RecvEchoReply(SOCKET s, LPSOCKADDR_IN lpsaFrom, u_char *pTTL)
{
	ECHOREPLY echoReply;
	int nRet;
	int nAddrLen = sizeof(struct sockaddr_in);

	// Receive the echo reply	
	nRet = recvfrom(s,					// socket
					(LPSTR)&echoReply,	// buffer
					sizeof(ECHOREPLY),	// size of buffer
					0,					// flags
					(LPSOCKADDR)lpsaFrom,	// From address
					&nAddrLen);			// pointer to address len

	// Check return value

	// return time sent and IP TTL
	*pTTL = echoReply.ipHdr.TTL;

	return(echoReply.echoRequest.dwTime);   		
}

UINT PingThread( LPVOID pParam )
{
	CThreadInfo* pThreadInfo = (CThreadInfo*)pParam;
	HWND	m_hWnd = pThreadInfo->m_hwndNotifyWnd;	

 	SOCKET	  rawSocket;
 	struct    sockaddr_in saDest;
 	struct    sockaddr_in saSrc;
 	LPHOSTENT lpHost;
 	CString str;
 	int nRet;
 	DWORD	  dwTimeSent,dwElapsed;
 	u_char    cTTL;
	long	m_laddr;

 	rawSocket = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
	while (TRUE)
	{			
		if (WaitForSingleObject(pThreadInfo->m_hEventStartPing,INFINITE)
			!= WAIT_OBJECT_0)		
			break;		
		if (WaitForSingleObject(pThreadInfo->m_hEventKillPing,0)
			== WAIT_OBJECT_0)
			break;
		str.Format("读取计算机:%s地址",pThreadInfo->strHost);
		::SendMessage(m_hWnd,WM_MSG_STATUS,0,(LPARAM) LPCTSTR(str));			
		m_laddr = inet_addr(pThreadInfo->strHost);
		if (m_laddr == INADDR_NONE)
		{
			lpHost = gethostbyname(pThreadInfo->strHost);
 			if (lpHost == NULL)
 			{
 				str.Format("计算机名字无效: %s", pThreadInfo->strHost);
				::PostMessage(m_hWnd,WM_MSG_STATUS, 0, (LPARAM) LPCTSTR (str));
				::PostMessage(m_hWnd,WM_MSG_PINGSTOP,0,0);	
				::PostMessage(m_hWnd,WM_MSG_STATUS, 0, (LPARAM) "完成!");	
				continue;
			}
 			saDest.sin_addr.s_addr = *((u_long FAR *) (lpHost->h_addr));
		}
		else
		{
			saDest.sin_addr.s_addr =m_laddr;
		}
 		saDest.sin_family = AF_INET;
 		saDest.sin_port = 0;
 		str.Format("Pinging %s [%s] with %d bytes of data:",
 				pThreadInfo->strHost,
 				inet_ntoa(saDest.sin_addr),
 				REQ_DATASIZE);
		::PostMessage(m_hWnd,WM_MSG_STATUS, 0, (LPARAM) LPCTSTR (str));
		if (WaitForSingleObject(pThreadInfo->m_hEventKillPing,0)
			== WAIT_OBJECT_0)
			break;
 		for (int nLoop = 0; nLoop < pThreadInfo->nRetries; nLoop++)
 		{
 			// Send ICMP echo request
			if (WaitForSingleObject(pThreadInfo->m_hEventStopPing,0)
				== WAIT_OBJECT_0)
				break;		
			if (WaitForSingleObject(pThreadInfo->m_hEventKillPing,0)
				== WAIT_OBJECT_0)
				break;		
 			SendEchoRequest(rawSocket, &saDest);
 			nRet = WaitForEchoReply(rawSocket);
 			if (!nRet)
 			{
 				str.Format("超时");
 				::PostMessage(m_hWnd,WM_MSG_STATUS, 0, (LPARAM) LPCTSTR (str));
 			}
 			else
 			{
 				// Receive reply
 				dwTimeSent = RecvEchoReply(rawSocket, &saSrc, &cTTL);
				// Calculate elapsed time
 				dwElapsed = GetTickCount() - dwTimeSent;
 				str.Format("Reply[%d] from: %s: bytes=%d time=%ldms TTL=%d", 
 				nLoop+1,
 				inet_ntoa(saSrc.sin_addr), 
 				REQ_DATASIZE,
 				dwElapsed,
 				cTTL);
 				::PostMessage(m_hWnd,WM_MSG_STATUS, 0, (LPARAM) LPCTSTR (str));				

 			}			
 		} 	 	
 		
		::PostMessage(m_hWnd,WM_MSG_PINGSTOP,0,0);	
		::PostMessage(m_hWnd,WM_MSG_STATUS, 0, (LPARAM) "完成!");	
		if (WaitForSingleObject(pThreadInfo->m_hEventKillPing,0)
			== WAIT_OBJECT_0)
			break;		
	}
	nRet = closesocket(rawSocket);
	ResetEvent(pThreadInfo->m_hEventKillPing);
	SetEvent(pThreadInfo->m_hEvenPingtKilled);	
	return 1;
}

⌨️ 快捷键说明

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