这篇文章主要介绍了C++代码实现网络Ping功能,Ping命令被送到本地计算机的IP软件,该命令永不退出该计算机,本文给大家介绍的非常详细,需要的朋友参考下吧
ping 127.0.0.1: 这个Ping命令被送到本地计算机的IP软件,该命令永不退出该计算机。
localhost是个操作系统的网络保留名,是127.0.0.1的别名。
ping www.baidu.com――对这个域名执行Ping命令,你的计算机必须先将域名转换成IP地址,通常是通过DNS服务器。
(一)main.cpp文件
// ConsoleApplication3.cpp : 定义控制台应用程序的入口点。 // //程序应用: ping命令是向目的主机发送ICMP报文,检验本地主机和远程的目的主机是否连接 #include#include #include "ping.h" int main(void) { CPing objPing; //CPing类与对象 char *szDestIP = "127.0.0.1"; //字符IP地址 //127.0.0.1 这个Ping命令被送到本地计算机的IP软件,该命令永不退出该计算机。localhost是个操作系统的网络保留名,是127.0.0.1的别名。//ping www.baidu.com――对这个域名执行Ping命令,你的计算机必须先将域名转换成IP地址,通常是通过DNS服务器。 PingReply reply; //PingReply类与对象 printf("Pinging %s with %d bytes of data:\n", szDestIP, DEF_PACKET_SIZE); //ping 远端IP地址,32字节的数据 while (TRUE) { objPing.Ping(szDestIP, &reply);//远端IP地址不为空(NULL),就返回true表示需要响应报文。远端IP空时不需要响应报文false。 printf("Reply from %s: bytes=%d time=%ldms TTL=%ld\n", szDestIP, reply.m_dwBytes, reply.m_dwRoundTripTime, reply.m_dwTTL); //字节数,时间,TTL生存时间 Sleep(500); } return 0; }
(二)ping.h文件
(1)IP头结构体:
IHL:首部长度。因为IP的头部不是定长的,所以需要这个信息进行IP包的解析,从而找到Data字段的起始点。
另外注意这个IHL是以4个字节为单位的,所以首部实际长度是IHL*4字节。
Time to Live:生存时间,这个就是TTL了。
Data:这部分是IP包的数据,也就是ICMP的报文内容。
//1.IP头结构体:20字节 struct IPHeader { BYTE m_byVerHLen; //4位版本Version+4位首部长度IHL 1B BYTE m_byTOS; //服务类型 1B=16b USHORT m_usTotalLen; //总长度 2B=16b USHORT m_usID; //标识 2B=16b USHORT m_usFlagFragOffset; //3位标志+13位片偏移=16位 2B=16b BYTE m_byTTL; //TTL 生存时间 1B=8b BYTE m_byProtocol; //协议 1B=8b 为1时表示是ICMP报文 USHORT m_usHChecksum; //首部检验和 2B=16b ULONG m_ulSrcIP; //源IP地址 4B=32b ULONG m_ulDestIP; //目的IP地址 4B=32b };
(2)ICMP头结构体:
类型Type、代码Code、校验和、标识符、序列号、ICMP数据
//ICMP报文由首部8B和数据段组成。 //首部为定长的8个字节,前4个字节是通用部分(类型1B/代码1B/校验和2B),后4个字节随报文类型的不同有所差异。 //2.ICMP头结构体 (标准ICMP头为8字节) struct ICMPHeader { BYTE m_byType; //类型 1B type=8表示响应请求报文,type=0表示响应应答报文。 BYTE m_byCode; //代码 1B 与type组合,表示具体的信息 USHORT m_usChecksum; //检验和 2B 整个ICMP报文的检验和,包括Type、Code、...、Data。 USHORT m_usID; //标识符 2B=16bits 用于标识本进程 USHORT m_usSeq; //序列号 2B=16bits 用于判断回显应答数据报。 ULONG m_ulTimeStamp; //时间戳(非标准ICMP头部)4B //统计ping的往返时间的做法是,在ICMP报文的Data区域写入4个字节的时间戳。在收到应答报文时,取出这个时间戳与当前的时间对比即可。 };
(3)ICMP响应报文结构体:
//3.ICMP回答报文结构体 struct PingReply { USHORT m_usSeq; //ICMP包的序列号 2B DWORD m_dwRoundTripTime;//时间差 4B (word是2字节) DWORD m_dwBytes; //数据所占字节数 4B DWORD m_dwTTL; //TTL生存时间 4B };
(4)Ping类及相关变量的定义:
//类 class CPing { //公共变量 public: CPing(); //构造函数 ~CPing(); //析构函数 BOOL Ping(DWORD dwDestIP, PingReply *pPingReply = NULL, DWORD dwTimeout = 2000); BOOL Ping(char *szDestIP, PingReply *pPingReply = NULL, DWORD dwTimeout = 2000); //私有变量 private: BOOL PingCore(DWORD dwDestIP, PingReply *pPingReply, DWORD dwTimeout); USHORT CalCheckSum(USHORT *pBuffer, int nSize);//计算检验和 ULONG GetTickCountCalibrate(); //计算毫秒级别的时间差 private: SOCKET m_sockRaw; //需要监听的socket以上就是C++代码实现网络Ping功能的详细内容,更多请关注0133技术站其它相关文章!