一种比较简单的实现ping的方式
<span style="font-family: Arial, Helvetica, sans-serif;">头文件</span>
<span style="font-family: Arial, Helvetica, sans-serif;">
</span>
<span style="font-family: Arial, Helvetica, sans-serif;">#ifndef __PING_H__</span>
#define __PING_H__
//
// Ping.h
//
#pragma once
#pragma pack(1)
#include <winsock2.h>
#define ICMP_ECHOREPLY	0
#define ICMP_ECHOREQ	8
#define PINGERR_SOCKET_ERROR -1
#define PINGERR_TIMEOUT      -2
#define PINGERR_NOHOST       -3
class CPing
{
public:
	int Ping(int ip);
protected:
	int  WaitForEchoReply(SOCKET s);
	// ICMP Echo Request/Reply functions
	int		SendEchoRequest(SOCKET, LPSOCKADDR_IN);
	DWORD	RecvEchoReply(SOCKET, LPSOCKADDR_IN, u_char *);
	u_short in_cksum(u_short *addr, int len);
};
// IP Header -- RFC 791
typedef struct tagIPHDR
{
	u_char  VIHL;			// Version and IHL
	u_char	TOS;			// Type Of Service
	short	TotLen;			// Total Length
	short	ID;				// Identification
	short	FlagOff;		// Flags and Fragment Offset
	u_char	TTL;			// Time To Live
	u_char	Protocol;		// Protocol
	u_short	Checksum;		// Checksum
	struct	in_addr iaSrc;	// Internet Address - Source
	struct	in_addr iaDst;	// Internet Address - Destination
}IPHDR, *PIPHDR;
// ICMP Header - RFC 792
typedef struct tagICMPHDR
{
	u_char	Type;			// Type
	u_char	Code;			// Code
	u_short	Checksum;		// Checksum
	u_short	ID;				// Identification
	u_short	Seq;			// Sequence
	char	Data;			// Data
}ICMPHDR, *PICMPHDR;
#define REQ_DATASIZE 32		// Echo Request Data size
// ICMP Echo Request
typedef struct tagECHOREQUEST
{
	ICMPHDR icmpHdr;
	DWORD	dwTime;
	char	cData[REQ_DATASIZE];
}ECHOREQUEST, *PECHOREQUEST;
// ICMP Echo Reply
typedef struct tagECHOREPLY
{
	IPHDR	ipHdr;
	ECHOREQUEST	echoRequest;
	char    cFiller[256];
}ECHOREPLY, *PECHOREPLY;
#pragma pack()
#endif
实现
//
// THIS CODE IS BASED ON THE CODE FROM
// THE BOOK WINSOCK 2.0 BY LEWIS NAPPER...
//
//
#include "ping.h"
#include <Mmsystem.h>
#pragma comment( lib,"winmm.lib" )
#pragma comment(lib,"ws2_32.lib")
int CPing::Ping(int ip)
{
	SOCKET	  rawSocket;
	int       nRet;
	struct    sockaddr_in saDest;
	struct    sockaddr_in saSrc;
	DWORD	  dwTimeSent;
	DWORD	  dwElapsed;
	u_char    cTTL;
	// Create a Raw socket
	rawSocket = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
	if (rawSocket == SOCKET_ERROR)
	{
		return PINGERR_SOCKET_ERROR;
	}
	// Setup destination socket address
	saDest.sin_addr.s_addr = ip;
	saDest.sin_family = AF_INET;
	saDest.sin_port   = 0;
    // Send ICMP echo request
    SendEchoRequest(rawSocket, &saDest);
    nRet = WaitForEchoReply(rawSocket);
    if (nRet == SOCKET_ERROR)
    {
        return PINGERR_SOCKET_ERROR;
    }
    if (!nRet)
    {
        return PINGERR_TIMEOUT;
    }
    else
    {
        // Receive reply
        dwTimeSent = RecvEchoReply(rawSocket, &saSrc, &cTTL);
        // Calculate elapsed time
        dwElapsed = timeGetTime() - dwTimeSent;
    }
    nRet = closesocket(rawSocket);
    return (int)dwElapsed;
}
int CPing::SendEchoRequest(SOCKET s,LPSOCKADDR_IN lpstToAddr)
{
	static ECHOREQUEST echoReq;
	static int nId = 1;
	static int nSeq = 1;
	int nRet;
	// Fill in echo request
	echoReq.icmpHdr.Type		= ICMP_ECHOREQ;
	echoReq.icmpHdr.Code		= 0;
	echoReq.icmpHdr.Checksum	= 0;
	echoReq.icmpHdr.ID			= u_short(nId++);
	echoReq.icmpHdr.Seq			= u_short(nSeq++);
	// Fill in some data to send
	for (nRet = 0; nRet < REQ_DATASIZE; nRet++)
		echoReq.cData[nRet] = char(' '+nRet);
	// Save tick count when sent
	echoReq.dwTime				= timeGetTime();
	// 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);
}
DWORD CPing::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
	// return time sent and IP TTL
	*pTTL = echoReply.ipHdr.TTL;
	return(echoReply.echoRequest.dwTime);
}
int CPing::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));
}
//
// Mike Muuss' in_cksum() function
// and his comments from the original
// ping program
//
// * Author -
// *	Mike Muuss
// *	U. S. Army Ballistic Research Laboratory
// *	December, 1983
/*
 *			I N _ C K S U M
 *
 * Checksum routine for Internet Protocol family headers (C Version)
 *
 */
u_short CPing::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 = u_short(~sum);				/* truncate to 16 bits */
	return (answer);
}
												
											一种比较简单的实现ping的方式的更多相关文章
- CSharpGL(40)一种极其简单的半透明渲染方法
		
CSharpGL(40)一种极其简单的半透明渲染方法 开始 这里介绍一个实现半透明渲染效果的方法.此方法极其简单,不拖累渲染速度,但是不能适用所有的情况. 如下图所示,可以让包围盒显示为半透明效果. ...
 - 简单总结几种常见web攻击手段及其防御方式
		
web攻击手段有几种,本文简单介绍几种常见的攻击手段及其防御方式 XSS(跨站脚本攻击) CSRF(跨站请求伪造) SQL注入 DDOS XSS 概念 全称是跨站脚本攻击(Cross Site Scr ...
 - 简单地总结几种常见web攻击手段及其防御方式
		
web攻击手段有几种,本文简单介绍几种常见的攻击手段及其防御方式 XSS(跨站脚本攻击) CSRF(跨站请求伪造) SQL注入 DDOS XSS 概念 全称是跨站脚本攻击(Cross Site Scr ...
 - 用 Java 技术创建 RESTful Web (服务 JAX-RS:一种更为简单、可移植性更好的替代方式)
		
作者: Dustin Amrhein, 软件工程师, IBM Nick Gallardo, 软件工程师, IBM 出处: http://www.ibm.com/developerworks/cn/we ...
 - [1.6W字] 浏览器跨域请求限制的详细原理分析&寻找一种最简单的方式实现XHR跨域(9种方法, 附大招可以纯前端实现跨域!)
		
Title/ 浏览器跨域(CrossOrigin)请求的原理, 以及解决方案详细指南 #flight.Archives011 序: 最近看到又有一波新的创作活动了, 官方给出的话题中有一个" ...
 - Android两种为ViewPager+Fragment添加Tab的方式
		
在Android开发中ViewPager的使用是非常广泛的,而它不仅仅能够实现简单的开始引导页,还可以结合Fragment并添加Tab作为选项卡或为显示大批量页面实现强大的顺畅滑动 下面介绍两种为Vi ...
 - 在.NET Core中三种实现“可插拔”AOP编程方式(附源码)
		
一看标题肯定会联想到使用动态编织的方式实现AOP编程,不过这不是作者本文讨论的重点. 本文讨论另外三种在netcore中可实现的方式,Filter(过滤器,严格意义上它算是AOP方式),Dynamic ...
 - 几种常见web攻击手段及其防御方式
		
XSS(跨站脚本攻击) CSRF(跨站请求伪造) SQL注入 DDOS web安全系列目录 总结几种常见web攻击手段极其防御方式 总结几种常见的安全算法 XSS 概念 全称是跨站脚本攻击(Cross ...
 - 总结几种常见web攻击手段及其防御方式
		
本文简单介绍几种常见的攻击手段及其防御方式 XSS(跨站脚本攻击) CSRF(跨站请求伪造) SQL注入 DDOS web安全系列目录 总结几种常见web攻击手段极其防御方式 总结几种常见的安全算法 ...
 
随机推荐
- 前端异常监控 - BadJS
			
前端异常监控 - BadJS 简介:BadJS 是 web 前端异常监控解决方案,提供一种 web 页面的脚本错误监控.上报.统计.查看等系统化的跟踪解决方案.目前BadJS覆盖了腾讯课堂.公众号.邮 ...
 - 5 款最新的 jQuery 图片裁剪插件
			
这篇文章主要介绍最新的 5 款 jQuery 图片裁剪插件,可以帮助你轻松的实现你网站需要的图像裁剪功能. Cropit Cropit 是一个 jQuery 插件,支持图像裁剪和缩放功能.Cropit ...
 - 【转】iframe页面跳转时,导致父页面滚动!该怎么解决?
			
HTML code <body> <form id="form1" runat="server"> <iframe id=&quo ...
 - python+selenium+unnittest框架
			
python+selenium+unnittest框架,以百度搜索为例,做了一个简单的框架,先看一下整个项目目录结构 我用的是pycharm工具,我觉得这个工具是天使,超好用也超好看! 这些要感谢原作 ...
 - spring boot mybatis 整合教程
			
本项目使用的环境: 开发工具:Intellij IDEA 2017.1.3 springboot: 1.5.6 jdk:1.8.0_161 maven:3.3.9 额外功能 PageHelper 分页 ...
 - 【hive】 hive 加载数据
			
1. insert 插入数据 要保证启动了jobhistory 否则会抛出异常 hdfs中查看内容 2. create table 表名字 select 字段... from 表名 hdfs查看数据 ...
 - [Bayes] Understanding Bayes: Updating priors via the likelihood
			
From: https://alexanderetz.com/2015/07/25/understanding-bayes-updating-priors-via-the-likelihood/ Re ...
 - [TensorBoard] *Cookbook - Tensorboard
			
Ref: https://www.tensorflow.org/get_started/summaries_and_tensorboard 可视化对于Training的重要性,不言而喻. 代码示范 # ...
 - 8 -- 深入使用Spring -- 6...1 Spring支持的事务策略
			
8.6.1 Spring支持的事务策略 JTA.JDBC.Hibernate Java EE应用的传统事务有两种策略:全局事务和局部事务.全局事务由应用服务器管理,需要底层服务器的JTA(Java T ...
 - SpringMVC -- @RequestMapping -- 随记
			
@RequestMapping RequestMapping是一个用来处理请求地址映射的注解,可用于类或方法上.用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径. RequestMappi ...