C++实现通过ICMP实现ping, 计算网络抖动,时延与丢包率

文章目录

    • 目的
    • 关于ICMP
    • socket 编程实现ICMP
      • 编译error
      • 代码
    • 参考博客
    • 扩展了解

目的

通过C++编程实现ping, 也算是对于SOCKET编程初步了解掌握。

  • 了解ICMP协议
  • 了解对应socket编程

关于ICMP

请参考我的博客Ping工作原理

socket 编程实现ICMP

Ping 使用 Internet 控制消息协议(ICMP)来测试主机之间的连通性。当用客户端发送一个 ping 请求时,则对应的发送一个 ICMP Echo 请求消息到目标主机,并等待目标主机回复一个 ICMP Echo 回应消息。如果目标主机接收到请求并且网络连接正常,则会返回一个回应消息,表示主机之间的网络连接是正常的。如果目标主机没有收到请求消息或网络连接不正常,则不会有回应消息返回。

编译error

  • winsock2.h 与 windows.h 先后顺序导致编译错误
    在Windows环境下编程不可避免的会用到windows.h和winsock.h头文件,在默认情况下windows.h头文件会包含winsock.h,此时当尝试包含winsock.h时就会出现头文件定义冲突的情况。解决这个冲突的方式有两种,第一种,在头部定义#define WIN32_LEAN_AND_MEAN来主动去除winsock.h头文件包含。第二种是将#include <winsock2.h>头文件,放在#include<windows.h>之前。两种方式均可,这些方法在进行Windows套接字编程时非常重要,可以防止头文件冲突,确保编译顺利进行。

  • IPExport.h导致编译错误
    还有一种是我遇到的 OptionsData 未知重写说明符, Data 未知重写说明符
    需要将如下注释掉就行, 具体原因后续有时间整理下。

//#include <iphlpapi.h>
//#include <icmpapi.h>

代码

  • ICMPDataHeader.h

相关头文件声明 与 数据定义


#pragma once#define WIN32_LEAN_AND_MEAN
#include <iostream>
#include <vector>
#include <cmath>
#include <chrono>
#include <ctime>
//#include <iphlpapi.h>
//#include <icmpapi.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#include <stdlib.h>#pragma comment(lib, "ws2_32.lib")
//#pragma comment(lib, "iphlpapi.lib")#define IP_RECORD_ROUTE  0x7// IP header structure
typedef struct _iphdr
{//Suppose the BYTE_ORDER is LITTLE_ENDIANunsigned int   h_len:4;        // Length of the headerunsigned int   version:4;      // Version of IPunsigned char  tos;            // Type of serviceunsigned short total_len;      // Total length of the packetunsigned short id;             // Unique identificationunsigned short frag_offset;    // Fragment offsetunsigned char  ttl;            // Time to liveunsigned char  protocol;       // Protocol (TCP, UDP etc)unsigned short checksum;       // IP checksumunsigned int   sourceIP;       // Source IPunsigned int   destIP;         // Destination IP
} IpHeader;#define ICMP_ECHO        8
#define ICMP_ECHOREPLY   0
#define ICMP_MIN         8 // Minimum 8-byte ICMP packet (header)// ICMP header structure
// This is not the standard header, but we reserve space for time
typedef struct _icmphdr
{BYTE   i_type;BYTE   i_code;                 // Type sub codeUSHORT i_cksum;USHORT i_id;USHORT i_seq;ULONG  timestamp;
} IcmpHeader;// IP option header - use with socket option IP_OPTIONS
typedef struct _ipoptionhdr
{unsigned char code;        // Option typeunsigned char len;         // Length of option hdrunsigned char ptr;         // Offset into optionsunsigned long addr[9];     // List of IP addrs
} IpOptionHeader;#define DEF_PACKET_SIZE  32        // Default packet size
#define MAX_PACKET       1024      // Max ICMP packet size
#define MAX_IP_HDR_SIZE  60        // Max IP header size w/options
  • 关键核心代码 cpp
校验函数
#include "icmppacketprocessor.h"ICMPPacketProcessor::ICMPPacketProcessor(QObject* parent):QObject{parent}
{}ICMPPacketProcessor::~ICMPPacketProcessor()
{if(lpdest){delete lpdest;}
}unsigned short ICMPPacketProcessor::checksum(unsigned short *buffer, int size)
{unsigned long cksum=0;while(size > 1){cksum += *buffer++;size -= sizeof(unsigned short);}if(size){cksum += *(UCHAR*)buffer;}cksum = (cksum >> 16) + (cksum & 0xffff);cksum += (cksum >>16);return (unsigned short)(~cksum);
}// Function: FillICMPData
// Description:
//    Helper function to fill in various fields for our ICMP request
void ICMPPacketProcessor::fillICMPData(char *icmp_data, int datasize)
{IcmpHeader *icmp_hdr = NULL;char *datapart = NULL;icmp_hdr = (IcmpHeader*)icmp_data;icmp_hdr->i_type = ICMP_ECHO; // Request an ICMP echo, type is 8icmp_hdr->i_code = 0;    // code is 0icmp_hdr->i_id = (USHORT)GetCurrentProcessId();icmp_hdr->i_cksum = 0;icmp_hdr->i_seq = 0;datapart = icmp_data + sizeof(IcmpHeader);// Place some junk in the buffermemset(datapart, 'E' , datasize - sizeof(IcmpHeader));
}
// Function: DecodeIPOptions
// Description:
//    If the IP option header is present, find the IP options
//    within the IP header and print the record route option values
void ICMPPacketProcessor::decodeIPOptions(char *buf, int bytes)
{IpOptionHeader *ipopt = NULL;IN_ADDR         inaddr;int             i;HOSTENT        *host = NULL;ipopt = (IpOptionHeader *)(buf + 20);printf("Record Route:   ");for(i = 0; i < (ipopt->ptr / 4) - 1; i++){inaddr.S_un.S_addr = ipopt->addr[i];if (i != 0) printf("   ");host = gethostbyaddr(

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/819703.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《Stable Diffusion AI绘画宝典:从入门到精通,解锁创意新境界》

前沿 在数字化浪潮席卷全球的时代&#xff0c;人工智能以其惊人的创造力和创新性引领着科技新风尚。党的二十大报告明确提出了“实施科教兴国战略&#xff0c;强化现代化建设人才支撑”的宏伟蓝图&#xff0c;展现了我国在新动能、新优势方面的坚定决心和强大气魄。在这个大背…

【Linux】进程的优先级环境变量

个人主页 &#xff1a; zxctscl 如有转载请先通知 文章目录 1. 前言2. 进程的优先级2.1 什么是优先级2.2 为什么要有优先级2.3 优先级的查看方式2.4 对优先级调整 3. 命令行参数4. 环境变量4.1 环境变量与配置文件4.1.1 环境变量初步介绍4.1.2 配置文件 4.2 更多环境变量4.3 整…

Postgresql源码(125)游标恢复执行的原理分析

问题 为什么每次fetch游标能从上一次的位置继续&#xff1f;后面用一个简单用例分析原理。 【速查】 恢复扫描需要知道当前页面、上一次扫描到的偏移位置、当前页面一共有几条&#xff1a; 当前页面&#xff1a;HeapScanDesc结构中记录了扫到的页面&#xff08;scan->rs_cb…

Apache Paimon 流式湖仓介绍说明

文章目录 前言选择 Paimon 的原因Apache Paimon 功能一致性保证Paimon 表类型数据湖写入标签和时间线回溯捕获变更数据写入数据湖LSM 和分层文件重用流处理案例使用 Paimon 作为消息队列 前言 Apache Flink 自诞生以来经历了重大演变&#xff0c;如今&#xff0c;它不仅充当批…

毕设选51还是stm32?51太简单?

如果你更倾向于挑战和深入学习&#xff0c;STM32可能是更好的选择。如果你希望更专注于底层硬件原理&#xff0c;51可能更适合。我这里有一套嵌入式入门教程&#xff0c;不仅包含了详细的视频讲解&#xff0c;项目实战。如果你渴望学习嵌入式&#xff0c;不妨点个关注&#xff…

正则表达式中 “$” 并不是表示 “字符串结束

作者&#xff1a;Seth Larson 译者&#xff1a;豌豆花下猫Python猫 英文&#xff1a;Regex character “$” doesnt mean “end-of-string” 转载请保留作者及译者信息&#xff01; 这篇文章写一写我最近在用 Python 的正则表达式模块&#xff08;re&#xff09;开发 CPyth…

c++ 面向对象之 Lambda 表达式

一、简介 Lambda 表达式是 c11 中语法之一&#xff08;所以不要在 dev c 没添加 -stdc11/-stdc14 时使用了&#xff0c;等待你的是报错&#xff09;。Lambda 表达式把函数看作对象&#xff0c;把这个表达式当做对象使用。 二、使用 Lambda 表达式难以声明类型&#xff0c;故使…

阿里云迁移到AWS云,九河云保姆级教程

随着云计算技术的不断发展,越来越多的企业开始将传统的IT基础设施迁移到云平台上,以获得更高的灵活性、可扩展性和成本效益。在众多云服务提供商中,阿里云和AWS都是备受青睐的选择。本文将探讨如何将阿里云上的资源顺利迁移到AWS云平台,并针对性地进行优化。我们九河云&#xf…

[图解]DDD领域驱动设计伪创新-聚合根06

0 00:00:00,740 --> 00:00:02,200 那刚才讲了 1 00:00:02,480 --> 00:00:04,211 Evans这个隐喻 2 00:00:04,211 --> 00:00:06,520 实际上背后是把集合 3 00:00:06,800 --> 00:00:08,560 当成了聚合 4 00:00:10,580 --> 00:00:14,350 那为什么有这样的一个隐…

OpenHarmony实战开发-如何使用AKI轻松实现跨语言调用。

介绍 针对JS与C/C跨语言访问场景&#xff0c;NAPI使用比较繁琐。而AKI提供了极简语法糖使用方式&#xff0c;一行代码完成JS与C/C的无障碍跨语言互调&#xff0c;使用方便。本示例将介绍使用AKI编写C跨线程调用JS函数场景。通过调用C全局函数&#xff0c;创建子线程来调用JS函…

阿尔法编程使用

使用登录 平台地址&#xff1a;https://nuc.alphacoding.cn/&#xff08;建议使用最新的chrome、firefox、safari、edge打开&#xff0c;不要从微信直接打开&#xff09; 教师体验账号&#xff1a;teacher01-teacher10&#xff0c;一共10个账号&#xff0c;密码是123456&#…

GIS 数据格式转换

1、在线工具 mapshaper 2、数据上传 3、数据格式转换 导入数据可导出为多种格式&#xff1a;Shapefile、Json、GeoJson、CSV、TopJSON、KML、SVG

APP广告变现项目

APP广告变现项目 很多人觉得不可能&#xff0c;这是肯定存在的&#xff0c;不是现在才有的一个项目&#xff0c;这个项目的原理是怎么样呢&#xff0c;就是通过某些特定的app&#xff0c;然后看完广告就有收益&#xff0c;基本单次的观看单价都是在几毛到1块之间。 养机养好的…

java面试题(7)|Java 中的 Set 集合是如何保证添加元素不重复的?

文章目录 HashSetTreeSetLinkedHashSet 在 Java 中&#xff0c;Set 集合通过其实现类来确保不包含重复元素。常见的实现类有 HashSet、TreeSet 和 LinkedHashSet。 HashSet HashSet 使用 HashMap 来存储元素&#xff0c;其中元素作为键&#xff0c;而值则是一个常量。当你尝试…

ES6 import / export / export default type=module

1.export可以导出多个变量&#xff0c;函数&#xff0c;变量&#xff0c;函数需要一个一个导出&#xff0c;也可以以对象的方式导出{}; 2.import的时候&#xff0c;也需要加{}&#xff0c;且变量名&#xff0c;函数名需要和导出的一样。 3.export default 只能导出一个对象&…

阿里云服务器带宽多少钱?公网带宽收费标准全解析

阿里云服务器的公网带宽计费模式分为“按固定带宽”和“按使用流量”&#xff0c;有什么区别&#xff1f;按固定带宽是指直接购买多少M带宽&#xff0c;比如1M、5M、10M、100M等&#xff0c;阿里云直接分配用户所购买的带宽值&#xff0c;根据带宽大小先付费再使用&#xff1b;…

ADC通道检测功能-单片机通用模板

ADC通道检测功能-单片机通用模板 使用ADC外设的流程&#xff1a; 先初始化ADC外设的时钟&#xff1b;选择ADC的参考电压以及需要采集的通道&#xff1b;ADSOC1 开始转换&#xff0c;死循环等待转换完成ADSOC0&#xff1b;从ADCDH、ADCDL数据寄存器取出ADC转换数值&#xff1b;…

一套3种风格经典的wordpress免费主题模板

wordpress免费企业主题 https://www.wpniu.com/themes/39.html 免费wordpress企业模板 https://www.wpniu.com/themes/43.html 免费wordpress企业主题 https://www.wpniu.com/themes/44.html

波奇学Linux:ip协议

ip报头是c语言的结构体 报头和有效载荷如何分离&#xff1f; 固定长度四位首部长度 4位版本号就是IPV4 8位服务类型&#xff1a;4位TOS位段和位保留字段 4位TOS分别表示&#xff1a;最小延时&#xff0c;最大吞吐量&#xff0c;最高可靠性&#xff0c;最小成本 给路由器提…

【JAVA基础篇教学】第十六篇:Java连接和操作MySQL数据库

博主打算从0-1讲解下java基础教学&#xff0c;今天教学第十六篇&#xff1a;Java连接和操作MySQL数据库。 我将提供一个简单的示例代码&#xff0c;涵盖数据库连接、查询、插入和更新等操作。 一、下载MySQL驱动包 1.下载地址&#xff1a;MySQL :: Download Connector/J 2.解…