- 浏览: 369734 次
- 性别:
- 来自: 苏州
文章分类
- 全部博客 (335)
- C++ (190)
- 设计模式 (43)
- 数据库技术 (5)
- 网络编程 (11)
- 自动化测试 (6)
- Linux (13)
- OpenSSL (10)
- MS Crypt API (5)
- SCM (2)
- English (4)
- Android (10)
- EMV规范 (1)
- Saturn Platform (0)
- C (10)
- SQL (2)
- ASP.NET (3)
- 英语口语学习 (3)
- 调试工具 (21)
- 编译技术 (5)
- UML (1)
- 项目管理 (5)
- 敏捷开发 (2)
- Http Server (6)
- 代码审查、代码分析 (5)
- 面试基础 (10)
- 重点知识 (16)
- STL (6)
- Efficient C++资料 (8)
- 数据结构和算法 (7)
- 读书笔记 (0)
- 开源项目 (4)
- 多线程 (2)
- Console App (6)
- 个人开源项目 (4)
- IBM DevelopWorks (4)
- Java (16)
- 内存泄漏相关调试和检测 (13)
- 软件测试相关技术 (2)
- C# (11)
- Apple Related (1)
- 软件测试和管理 (2)
- EMV (1)
- Python (1)
- Node.js (6)
- JavaScript (5)
- VUE (1)
- Frontend (1)
- Backend (4)
- RESTful API (3)
- Firebase (3)
最新评论
-
u013189503:
来个密码吧
[C++][Logging] 项目中写日志模块的实现 -
wyf_vc:
来个密码啊!!
[C++][Logging] 项目中写日志模块的实现
基础知识
ping的过程是向目的IP发送一个type=8的ICMP响应请求报文,目标主机收到这个报文之后,会向源IP(发送方,我)回复一个type=0的ICMP响应应答报文。
那上面的字节、往访时间、TTL之类的信息又是从哪来的呢?这取决于IP和ICMP的头部。
ping的过程是向目的IP发送一个type=8的ICMP响应请求报文,目标主机收到这个报文之后,会向源IP(发送方,我)回复一个type=0的ICMP响应应答报文。
那上面的字节、往访时间、TTL之类的信息又是从哪来的呢?这取决于IP和ICMP的头部。
#pragma once //在默认windows.h会包含winsock.h,当你包含winsock2.h就会冲突,因此在包含windows.h前需要定义一个宏,#define WIN32_LEAN_AND_MEAN ;去除winsock.h //要么将#include winsock2.h放在#includewindows.h前面或者直接去掉#includewindows.h #include winsock2.h #pragma comment(lib, WS2_32) 链接到WS2_32.lib #define DEF_PACKET_SIZE 32 #define ECHO_REQUEST 8 #define ECHO_REPLY 0 struct IPHeader { BYTE m_byVerHLen; 4位版本+4位首部长度 BYTE m_byTOS; 服务类型 USHORT m_usTotalLen; 总长度 USHORT m_usID; 标识 USHORT m_usFlagFragOffset; 3位标志+13位片偏移 BYTE m_byTTL; TTL BYTE m_byProtocol; 协议 USHORT m_usHChecksum; 首部检验和 ULONG m_ulSrcIP; 源IP地址 ULONG m_ulDestIP; 目的IP地址 }; struct ICMPHeader { BYTE m_byType; 类型 BYTE m_byCode; 代码 USHORT m_usChecksum; 检验和 USHORT m_usID; 标识符 USHORT m_usSeq; 序号 ULONG m_ulTimeStamp; 时间戳(非标准ICMP头部) }; struct PingReply { USHORT m_usSeq; DWORD m_dwRoundTripTime; DWORD m_dwBytes; DWORD m_dwTTL; }; 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; WSAEVENT m_event; USHORT m_usCurrentProcID; char m_szICMPData; BOOL m_bIsInitSucc; private static USHORT s_usPacketSeq; };
#include "ping.h" #include <iostream> USHORT CPing::s_usPacketSeq = 0; CPing::CPing() :m_szICMPData(NULL),m_bIsInitSucc(FALSE) { WSADATA WSAData; //WSAStartup(MAKEWORD(2, 2), &WSAData); if (WSAStartup(MAKEWORD(1, 1), &WSAData) != 0) { /*如果初始化不成功则报错,GetLastError()返回发生的错误信息*/ printf("WSAStartup() failed: %d\n", GetLastError()); return; } m_event = WSACreateEvent(); m_usCurrentProcID = (USHORT)GetCurrentProcessId(); //setsockopt(m_sockRaw); /*if ((m_sockRaw = WSASocket(AF_INET, SOCK_RAW, IPPROTO_ICMP, NULL, 0, 0)) != SOCKET_ERROR) { WSAEventSelect(m_sockRaw, m_event, FD_READ); m_bIsInitSucc = TRUE; m_szICMPData = (char*)malloc(DEF_PACKET_SIZE + sizeof(ICMPHeader)); if (m_szICMPData == NULL) { m_bIsInitSucc = FALSE; } }*/ m_sockRaw = WSASocket(AF_INET, SOCK_RAW, IPPROTO_ICMP, NULL, 0, 0); if (m_sockRaw == INVALID_SOCKET) { std::cerr << "WSASocket() failed:" << WSAGetLastError ()<< std::endl; //10013 以一种访问权限不允许的方式做了一个访问套接字的尝试。 } else { WSAEventSelect(m_sockRaw, m_event, FD_READ); m_bIsInitSucc = TRUE; m_szICMPData = (char*)malloc(DEF_PACKET_SIZE + sizeof(ICMPHeader)); if (m_szICMPData == NULL) { m_bIsInitSucc = FALSE; } } } CPing::~CPing() { WSACleanup(); if (NULL != m_szICMPData) { free(m_szICMPData); m_szICMPData = NULL; } } BOOL CPing::Ping(DWORD dwDestIP, PingReply *pPingReply, DWORD dwTimeout) { return PingCore(dwDestIP, pPingReply, dwTimeout); } BOOL CPing::Ping(char *szDestIP, PingReply *pPingReply, DWORD dwTimeout) { if (NULL != szDestIP) { return PingCore(inet_addr(szDestIP), pPingReply, dwTimeout); } return FALSE; } BOOL CPing::PingCore(DWORD dwDestIP, PingReply *pPingReply, DWORD dwTimeout) { //判断初始化是否成功 if (!m_bIsInitSucc) { return FALSE; } //配置SOCKET sockaddr_in sockaddrDest; sockaddrDest.sin_family = AF_INET; sockaddrDest.sin_addr.s_addr = dwDestIP; int nSockaddrDestSize = sizeof(sockaddrDest); //构建ICMP包 int nICMPDataSize = DEF_PACKET_SIZE + sizeof(ICMPHeader); ULONG ulSendTimestamp = GetTickCountCalibrate(); USHORT usSeq = ++s_usPacketSeq; memset(m_szICMPData, 0, nICMPDataSize); ICMPHeader *pICMPHeader = (ICMPHeader*)m_szICMPData; pICMPHeader->m_byType = ECHO_REQUEST; pICMPHeader->m_byCode = 0; pICMPHeader->m_usID = m_usCurrentProcID; pICMPHeader->m_usSeq = usSeq; pICMPHeader->m_ulTimeStamp = ulSendTimestamp; pICMPHeader->m_usChecksum = CalCheckSum((USHORT*)m_szICMPData, nICMPDataSize); //发送ICMP报文 if (sendto(m_sockRaw, m_szICMPData, nICMPDataSize, 0, (struct sockaddr*)&sockaddrDest, nSockaddrDestSize) == SOCKET_ERROR) { return FALSE; } //判断是否需要接收相应报文 if (pPingReply == NULL) { return TRUE; } char recvbuf[256] = { "\0" }; while (TRUE) { //接收响应报文 if (WSAWaitForMultipleEvents(1, &m_event, FALSE, 100, FALSE) != WSA_WAIT_TIMEOUT) { WSANETWORKEVENTS netEvent; WSAEnumNetworkEvents(m_sockRaw, m_event, &netEvent); if (netEvent.lNetworkEvents & FD_READ) { ULONG nRecvTimestamp = GetTickCountCalibrate(); int nPacketSize = recvfrom(m_sockRaw, recvbuf, 256, 0, (struct sockaddr*)&sockaddrDest, &nSockaddrDestSize); if (nPacketSize != SOCKET_ERROR) { IPHeader *pIPHeader = (IPHeader*)recvbuf; USHORT usIPHeaderLen = (USHORT)((pIPHeader->m_byVerHLen & 0x0f) * 4); ICMPHeader *pICMPHeader = (ICMPHeader*)(recvbuf + usIPHeaderLen); if (pICMPHeader->m_usID == m_usCurrentProcID //是当前进程发出的报文 && pICMPHeader->m_byType == ECHO_REPLY //是ICMP响应报文 && pICMPHeader->m_usSeq == usSeq //是本次请求报文的响应报文 ) { pPingReply->m_usSeq = usSeq; pPingReply->m_dwRoundTripTime = nRecvTimestamp - pICMPHeader->m_ulTimeStamp; pPingReply->m_dwBytes = nPacketSize - usIPHeaderLen - sizeof(ICMPHeader); pPingReply->m_dwTTL = pIPHeader->m_byTTL; return TRUE; } } } } //超时 if (GetTickCountCalibrate() - ulSendTimestamp >= dwTimeout) { return FALSE; } } } USHORT CPing::CalCheckSum(USHORT *pBuffer, int nSize) { unsigned long ulCheckSum = 0; while (nSize > 1) { ulCheckSum += *pBuffer++; nSize -= sizeof(USHORT); } if (nSize) { ulCheckSum += *(UCHAR*)pBuffer; } ulCheckSum = (ulCheckSum >> 16) + (ulCheckSum & 0xffff); ulCheckSum += (ulCheckSum >> 16); return (USHORT)(~ulCheckSum); } ULONG CPing::GetTickCountCalibrate() { static ULONG s_ulFirstCallTick = 0; static LONGLONG s_ullFirstCallTickMS = 0; SYSTEMTIME systemtime; FILETIME filetime; GetLocalTime(&systemtime); SystemTimeToFileTime(&systemtime, &filetime); LARGE_INTEGER liCurrentTime; liCurrentTime.HighPart = filetime.dwHighDateTime; liCurrentTime.LowPart = filetime.dwLowDateTime; LONGLONG llCurrentTimeMS = liCurrentTime.QuadPart / 10000; if (s_ulFirstCallTick == 0) { s_ulFirstCallTick = GetTickCount(); } if (s_ullFirstCallTickMS == 0) { s_ullFirstCallTickMS = llCurrentTimeMS; } return s_ulFirstCallTick + (ULONG)(llCurrentTimeMS - s_ullFirstCallTickMS); }
#include <winsock2.h> #include <stdio.h> #include "ping.h" int main(void) { CPing objPing; char *szDestIP = "127.0.0.1"; PingReply reply; printf("Pinging %s with %d bytes of data:\n", szDestIP, DEF_PACKET_SIZE); while (TRUE) { objPing.Ping(szDestIP, &reply); printf("Reply from %s: bytes=%d time=%ldms TTL=%ld\n", szDestIP, reply.m_dwBytes, reply.m_dwRoundTripTime, reply.m_dwTTL); Sleep(500); } return 0; }
- C__实现ping功能.zip (140.3 KB)
- 下载次数: 0
- Code.zip (3.4 KB)
- 下载次数: 3
发表评论
-
FreeRTOS
2022-03-05 16:31 248Ref https://blog.csdn.net/weix ... -
[Python][网络爬虫]
2020-09-28 16:36 0#!/usr/bin/python #coding: U ... -
[轉]网络七层协议
2019-03-20 12:21 343应用层 与其它计算机 ... -
串口通讯相关
2018-11-02 13:44 410https://bbs.csdn.net/wap/topics ... -
[转]C++验证IP是否可以PING通
2018-10-30 17:54 1325https://www.cnblogs.com/guoyz13 ... -
C++/MFC 換皮膚
2018-10-20 11:05 477https://blog.csdn.net/u01123991 ... -
WinCE 截屏 - C++ 代碼
2018-08-31 09:45 574// this function create a bmp ... -
Android NDK搭建環境
2017-11-27 13:25 580https://www.cnblogs.com/ut2016- ... -
8583协议相关
2017-10-17 13:38 5738583相关资料,整理中... -
Java高级应用之JNI
2017-06-19 09:00 600参考link http://www.cnblogs.com/l ... -
OpenSSL 编译环境搭建
2017-03-27 15:01 9061 安裝VS2008到 c:\Program Files (x ... -
最优非对称加密填充(OAEP)
2017-03-25 14:53 1582OpenSSL命令---rsautl http://blog. ... -
[Platform Builder] 设置SVM OS build Env
2016-11-10 11:39 01 copy one OSDesign Project to ... -
[Windows] System Error Codes(GetLastError )0-----5999
2016-10-26 13:28 1880ERROR_SUCCESS 0 (0x0) T ... -
开源Windows驱动程序框架
2016-09-17 21:35 871转自 http://code.csdn.net/news/28 ... -
c/c++代码中执行cmd命令
2016-09-14 14:50 1908转自 http://blog.csdn.net/slixinx ... -
C#使用C++标准DLL实例(包含callback)
2016-09-11 19:44 1086C++编写标准Win32DLL如下 头文件 /***** ... -
C#调用C++的DLL搜集整理的所有数据类型转换方式
2016-09-09 16:07 969转自 http://www.cnblogs.com/zeroo ... -
WinCE CPU使用率计算 测试工具
2016-09-08 16:14 991转自 http://blog.csdn.net/jan ... -
switch在C++与C#中的一些差异
2016-09-08 15:19 810参考链接 http://blog.csdn.net/weiwe ...
相关推荐
该编码用C++实现了ping功能,即PC机与PC机间的通讯功能。
【非原创】C++实现PING功能源代码,经测试无BUG,已封装成函数,直接调用ping函数即可使用,信息反馈是通过shell输出,可自行更改。
以上就是使用C++和WinSock2在Windows环境下实现ping命令的基本步骤。实际应用中,你可能还需要处理更多细节,如错误处理、多线程、命令行参数解析等。此外,由于Windows的安全策略限制,普通用户权限可能无法直接...
这个名为"C++ 实现 ping 功能解析实际 IP地址"的项目,旨在通过C++编程语言来模拟实现ping功能,不仅可以检测客户端与服务器之间的连通性,还能处理对IP地址和域名的解析。下面我们将深入探讨相关的知识点。 首先,...
下面我们将深入探讨两种在Windows下用C++实现ping功能的方法,并结合Qt库进行讲解。 首先,我们要理解ping的基本原理。Ping是Internet控制消息协议(ICMP)的一部分,它发送一个称为echo请求的数据包到目标主机,...
用C++实现了cmd命令行程序的ping命令,并能够将域名解析成实际的ip地址,详情请见博客地址:http://blog.csdn.net/goforwardtostep/article/details/52988142
C++实现ping功能时,需要创建一个ICMP类型的套接字,并发送ICMP回显请求到目标IP地址。 3. **数据包封装与解封装**:在发送ICMP回显请求时,需要将数据包封装成符合ICMP协议格式的结构体,包括类型、代码、校验和...
用C语言实现ping功能的源码,已在VC6.0环境下编译通过
在Windows CE(简称WinCE)操作系统中,网络...通过阅读和分析这个源代码,你可以更好地理解和学习如何在WinCE环境下用C++实现ping功能。这个程序可以作为你自定义网络诊断工具的基础,或者对网络编程有更深入的理解。
以下将详细介绍C++实现ping代码的相关知识点。 1. **C++编程语言**:C++是一种静态类型的、编译式的、通用的、大小写敏感的、不仅支持过程化编程,也支持面向对象编程的程序设计语言。在本项目中,C++被用来创建一...
在IT行业中,网络编程是不可或缺的一部分,...总结起来,用C++实现ping功能涉及网络编程基础、ICMP协议的理解以及原始套接字的使用。这个过程不仅可以帮助开发者提升网络编程技能,也有助于在实际工作中解决网络问题。
首先,让我们理解C++实现ping功能的基本原理。在C++中,我们不能直接调用操作系统底层的ping功能,而是需要通过系统调用来完成。通常,这涉及到使用套接字(socket)编程和发送ICMP数据包。在Windows操作系统上,...
通过分析和学习这个源代码,开发者不仅可以理解如何用C++实现ping功能,还能学习到MFC框架下的应用开发,以及如何利用Winsock进行网络编程。这对于深入理解和扩展网络相关的C++应用非常有帮助。
标题 "Ping的C++实现" 涉及到的是在C++编程语言中构建一个功能类似于操作系统内置的`ping`命令的程序。`ping`是一个网络诊断工具,它通过发送Internet控制消息协议(ICMP)回显请求报文来检查网络连接是否可达。下面...
可实现ping命令的ICMP包发送,对于了解及学习网络编程很有帮助
请大家编译成功后,在生成的exe文件右键管理员运行。
本文将深入探讨基于Socket实现Ping功能的源代码,涉及到的主要知识点包括Socket编程、原始套接字(SOCK_RAW)以及ICMP(Internet Control Message Protocol)协议。 首先,我们需要理解什么是Socket。Socket是操作...
2. **C++实现ping功能的关键点**: - **ICMP协议**:首先需要理解ICMP协议,它是Internet控制消息协议,主要用于错误报告和一些特殊控制信息。 - **套接字编程**:在C++中,我们需要使用套接字编程来创建和发送...