<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的方式的更多相关文章

  1. CSharpGL(40)一种极其简单的半透明渲染方法

    CSharpGL(40)一种极其简单的半透明渲染方法 开始 这里介绍一个实现半透明渲染效果的方法.此方法极其简单,不拖累渲染速度,但是不能适用所有的情况. 如下图所示,可以让包围盒显示为半透明效果. ...

  2. 简单总结几种常见web攻击手段及其防御方式

    web攻击手段有几种,本文简单介绍几种常见的攻击手段及其防御方式 XSS(跨站脚本攻击) CSRF(跨站请求伪造) SQL注入 DDOS XSS 概念 全称是跨站脚本攻击(Cross Site Scr ...

  3. 简单地总结几种常见web攻击手段及其防御方式

    web攻击手段有几种,本文简单介绍几种常见的攻击手段及其防御方式 XSS(跨站脚本攻击) CSRF(跨站请求伪造) SQL注入 DDOS XSS 概念 全称是跨站脚本攻击(Cross Site Scr ...

  4. 用 Java 技术创建 RESTful Web (服务 JAX-RS:一种更为简单、可移植性更好的替代方式)

    作者: Dustin Amrhein, 软件工程师, IBM Nick Gallardo, 软件工程师, IBM 出处: http://www.ibm.com/developerworks/cn/we ...

  5. [1.6W字] 浏览器跨域请求限制的详细原理分析&寻找一种最简单的方式实现XHR跨域(9种方法, 附大招可以纯前端实现跨域!)

    Title/ 浏览器跨域(CrossOrigin)请求的原理, 以及解决方案详细指南 #flight.Archives011 序: 最近看到又有一波新的创作活动了, 官方给出的话题中有一个" ...

  6. Android两种为ViewPager+Fragment添加Tab的方式

    在Android开发中ViewPager的使用是非常广泛的,而它不仅仅能够实现简单的开始引导页,还可以结合Fragment并添加Tab作为选项卡或为显示大批量页面实现强大的顺畅滑动 下面介绍两种为Vi ...

  7. 在.NET Core中三种实现“可插拔”AOP编程方式(附源码)

    一看标题肯定会联想到使用动态编织的方式实现AOP编程,不过这不是作者本文讨论的重点. 本文讨论另外三种在netcore中可实现的方式,Filter(过滤器,严格意义上它算是AOP方式),Dynamic ...

  8. 几种常见web攻击手段及其防御方式

    XSS(跨站脚本攻击) CSRF(跨站请求伪造) SQL注入 DDOS web安全系列目录 总结几种常见web攻击手段极其防御方式 总结几种常见的安全算法 XSS 概念 全称是跨站脚本攻击(Cross ...

  9. 总结几种常见web攻击手段及其防御方式

    本文简单介绍几种常见的攻击手段及其防御方式 XSS(跨站脚本攻击) CSRF(跨站请求伪造) SQL注入 DDOS web安全系列目录 总结几种常见web攻击手段极其防御方式 总结几种常见的安全算法 ...

随机推荐

  1. FOR XML PATH 可以将查询结果根据行输出成XML格式

    SELECT CAST(OrderID AS varchar)+',' as OrderNo FROM Product CAST函数用于将某种数据类型的表达式显式转换为另一种数据类型 SELECT C ...

  2. 【Linux高级驱动】input子系统框架

    [1.input子系统框架(drivers\input)] 如何得出某个驱动所遵循的框架?    1) 通过网络搜索    2) 自己想办法跟内核代码!         2.1 定位此驱动是属于哪种类 ...

  3. Oracle分割字符串 REGEXP_SUBSTR用法

    分割字符串中所有指定字符,然后成多行参数说明,参数1: 待分割字符串参数2:正则表达式参数3:起始位置,从第几个字符开始正则表达式匹配(默认为1)参数4:标识第几个匹配组,默认为1参数5:模式('i' ...

  4. Java知多少(82)标签、按钮和按钮事件简介

    标签和按钮也许是图形界面中最常见的两种组件,按钮又总是与激发动作事件有关. 标签 标签(JLabel)是最简单的Swing组件.标签对象的作用是对位于其后的界面组件作说明.可以设置标签的属性,即前景色 ...

  5. 【hive】 hive 加载数据

    1. insert 插入数据 要保证启动了jobhistory 否则会抛出异常 hdfs中查看内容 2. create table 表名字 select 字段... from  表名 hdfs查看数据 ...

  6. [hive] hive cli 命令行

    hive 版本 1.2.2 帮助信息 -d  属性 set   和 set -v 变量 hive --define    和  hivevar:变量名字 -e  不启动hive,执行完成后自动退出. ...

  7. MTK 屏幕旋转90度

    http://blog.csdn.net/ouo555/article/details/44806837 1.屏幕显示顺时针旋转90度 lk 横屏logo,顺时针旋转90度显示修改bootable/b ...

  8. js中的原型继承

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  9. linux相关(3)

    1. shell环境变量 能够存在于本shell进程及其子shell进程的变量.变量可以从父shell进程传递给子shell进程,而不能反过来,因此环境变量在子shell进程中无论如何修改都不会影响到 ...

  10. [原]openstack-kilo--issue(九) heat stacks topology中图形无法正常显示

    本博客已经添加"打赏"功能,"打赏"位置位于右边栏红色框中,感谢您赞助的咖啡. ======声明======= 欢迎转载:转载请注明出处 http://www. ...