RoundTrip测试RTT时延

网络时间同步(NTP)原理

网络时钟同步的工作过程如下:

  • Device A发送一个NTP报文给Device B,该报文带有它离开Device A时的时间戳,该时间戳为10:00:00am(T1)。

  • 当此NTP报文到达Device B时,Device B加上自己的时间戳,该时间戳为11:00:01am(T2)。

  • 当此NTP报文离开Device B时,Device B再加上自己的时间戳,该时间戳为11:00:02am(T3)。

  • 当Device A接收到该响应报文时,Device A的本地时间为10:00:03am(T4)。

NTP报文的往返时延Delay=(T4-T1)-(T3-T2)
Device A相对Device B的时间差offset=((T2-T1)+(T3-T4))/2

RounTrip代码分析

RoundTrip就是按照NTP时间同步的原理,实现一个测量两台机器之间时间误差的程序,在实现中服务端将收到数据的时间与发送应答的时间抽象为一个时间点,即忽略server端处理数据的时间误差。

代码位置:

  • UDP with muduo:muduo- master/examples/roundtrip/roundtrip_udp.cc
  • TCP with muduo:muduo- master/examples/roundtrip/roundtrip.cc

roundtrip_udp.cc服务端

void serverReadCallback(int sockfd, muduo::Timestamp receiveTime)
{int64_t message[2];struct sockaddr peerAddr;bzero(&peerAddr, sizeof peerAddr);socklen_t addrLen = sizeof peerAddr;ssize_t nr = ::recvfrom(sockfd, message, sizeof message, 0, &peerAddr, &addrLen);char addrStr[32];sockets::toIpPort(addrStr, sizeof addrStr, *reinterpret_cast<struct sockaddr_in*>(&peerAddr));LOG_DEBUG << "received " << nr << " bytes from " << addrStr;if (nr < 0){LOG_SYSERR << "::recvfrom";}else if (implicit_cast<size_t>(nr) == frameLen){// 记录一个时间戳 并返回给客户端message[1] = receiveTime.microSecondsSinceEpoch();ssize_t nw = ::sendto(sockfd, message, sizeof message, 0, &peerAddr, addrLen);if (nw < 0){LOG_SYSERR << "::sendto";}else if (implicit_cast<size_t>(nw) != frameLen){LOG_ERROR << "Expect " << frameLen << " bytes, wrote " << nw << " bytes.";}}else{LOG_ERROR << "Expect " << frameLen << " bytes, received " << nr << " bytes.";}
}

roundtrip_udp.cc客户端


void sendMyTime(int sockfd)
{int64_t message[2] = { 0, 0 };// 发送一个当下的时间戳message[0] = Timestamp::now().microSecondsSinceEpoch();ssize_t nw = sockets::write(sockfd, message, sizeof message);if (nw < 0){LOG_SYSERR << "::write";}else if (implicit_cast<size_t>(nw) != frameLen){LOG_ERROR << "Expect " << frameLen << " bytes, wrote " << nw << " bytes.";}
}void clientReadCallback(int sockfd, muduo::Timestamp receiveTime)
{int64_t message[2];ssize_t nr = sockets::read(sockfd, message, sizeof message);if (nr < 0){LOG_SYSERR << "::read";}else if (implicit_cast<size_t>(nr) == frameLen){int64_t send = message[0];int64_t their = message[1];int64_t back = receiveTime.microSecondsSinceEpoch();int64_t mine = (back+send)/2;	LOG_INFO << "round trip " << back - send	// 往返时间<< " clock error " << their - mine;	// 服务端相对客户端的时钟差}else{LOG_ERROR << "Expect " << frameLen << " bytes, received " << nr << " bytes.";}
}

roundtrip.cc Tcp的代码与上面类似

测试

同一机器下(127.0.0.1)

udp

20240506 13:14:09.259012Z 18477 INFO  round trip 707 clock error 66 - roundtrip_udp.cc:93
20240506 13:14:09.461553Z 18477 INFO  round trip 828 clock error 66 - roundtrip_udp.cc:93
20240506 13:14:09.662840Z 18477 INFO  round trip 952 clock error 57 - roundtrip_udp.cc:93
20240506 13:14:09.863861Z 18477 INFO  round trip 755 clock error 59 - roundtrip_udp.cc:93
20240506 13:14:10.064963Z 18477 INFO  round trip 855 clock error 71 - roundtrip_udp.cc:93
20240506 13:14:10.267029Z 18477 INFO  round trip 966 clock error -23 - roundtrip_udp.cc:93
20240506 13:14:10.470978Z 18477 INFO  round trip 829 clock error 40 - roundtrip_udp.cc:93
20240506 13:14:10.671284Z 18477 INFO  round trip 841 clock error 64 - roundtrip_udp.cc:93
20240506 13:14:10.872879Z 18477 INFO  round trip 951 clock error 97 - roundtrip_udp.cc:93
20240506 13:14:11.074060Z 18477 INFO  round trip 716 clock error 66 - roundtrip_udp.cc:93
20240506 13:14:11.275834Z 18477 INFO  round trip 873 clock error 38 - roundtrip_udp.cc:93
20240506 13:14:11.477013Z 18477 INFO  round trip 897 clock error 102 - roundtrip_udp.cc:93
20240506 13:14:11.679080Z 18477 INFO  round trip 741 clock error 70 - roundtrip_udp.cc:9 

tcp

20240506 13:14:13.321049Z 11109 INFO  round trip 1108 clock error -97 - roundtrip.cc:82
20240506 13:14:13.531021Z 11109 INFO  round trip 1079 clock error -79 - roundtrip.cc:82
20240506 13:14:13.740006Z 11109 INFO  round trip 1299 clock error -46 - roundtrip.cc:82
20240506 13:14:13.943726Z 11109 INFO  round trip 1104 clock error -89 - roundtrip.cc:82
20240506 13:14:14.148380Z 11109 INFO  round trip 1158 clock error -91 - roundtrip.cc:82
20240506 13:14:14.350723Z 11109 INFO  round trip 1295 clock error 89 - roundtrip.cc:82
20240506 13:14:14.551261Z 11109 INFO  round trip 1245 clock error -113 - roundtrip.cc:82
20240506 13:14:14.758256Z 11109 INFO  round trip 1744 clock error -351 - roundtrip.cc:82
20240506 13:14:14.962002Z 11109 INFO  round trip 1276 clock error -5 - roundtrip.cc:82
20240506 13:14:15.169267Z 11109 INFO  round trip 955 clock error -46 - roundtrip.cc:82
20240506 13:14:15.374836Z 11109 INFO  round trip 1113 clock error -108 - roundtrip.cc:82
20240506 13:14:15.579069Z 11109 INFO  round trip 1125 clock error -61 - roundtrip.cc:82
20240506 13:14:15.780133Z 11109 INFO  round trip 1013 clock error -63 - roundtrip.cc:82

round trip指代的是往返时间,clock error指代的是服务端相对客户端的时钟差,单位都是微秒。
总体相比,tcp所用的往返时间还是比udp的往返时间要长,而在同一机器下,理想状态下,时钟差应该为0才对,但是两种方式都各自计算出了不怎么接近0的数值。

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

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

相关文章

简单了解泛型

基本数据类型和对应的包装类 在Java中, 基本数据类型不是继承自Object, 为了在泛型代码中可以支持基本类型, Java给每个基本类型都对应了一个包装类型. 简单来说就是让基本数据类型也能面向对象.基本数据类型可以使用很多方法, 这就必须让它变成类. 基本数据类型对定的包装类…

如何O(1)判断一个数是不是x的幂

如何 O(1) 判断一个数是不是 x 的幂 (x 有限大) 数据在 32 位整数范围内 2 的幂 231. 2 的幂 - 力扣&#xff08;LeetCode&#xff09; 给你一个整数 n&#xff0c;请你判断该整数是否是 2 的幂次方。如果是&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。…

sql注入练习

1.什么是SQL注入 SQL注入是比较常见的网络攻击方式之一&#xff0c;它不是利用操作系统的BUG来实现攻击&#xff0c;而是针对程序员编写时的疏忽&#xff0c;通过SQL语句&#xff0c;实现无账号登录&#xff0c;甚至篡改数据库 2.sql注入原理 攻击者注入一段包含注释符的SQL语…

能将图片转为WebP格式的WebP Server Go

本文完成于 2023 年 11 月 之前老苏介绍过 webp2jpg-online&#xff0c;可以将 webp 格式的图片&#xff0c;转为 jpg 等&#xff0c;今天介绍的 WebP Server Go 是将 jpg 等转为 webp 格式 文章传送门&#xff1a;多功能图片转换器webp2jpg-online 什么是 WebP ? WebP 它是由…

Vue 路由

单应用程序 SPA - Single Page Application 所有功能在一个html页面上实现 单页面应用 多用于 系统类网站/内部网站/文档类网站/移动端站点 多页面应用 多用于 公司官网/电商类网站 路由 单页面应用按需更新页面&#xff0c;需要明确访问路径和组件的对应关系 Vue中的路…

重学java 30.API 1.String字符串

于是&#xff0c;虚度的光阴换来了模糊 —— 24.5.8 一、String基础知识以及创建 1.String介绍 1.概述 String类代表字符串 2.特点 a.Java程序中的所有字符串字面值(如“abc”)都作为此类的实例(对象)实现 凡是带双引号的&#xff0c;都是String的对象 String s "abc&q…

python面试之mysql引擎选择问题

MySQL数据库提供了多种存储引擎&#xff0c;每种存储引擎有其特定的优势和场景适用。以下是几种常见的MySQL存储引擎及其特点&#xff1a; InnoDB&#xff1a; 支持事务&#xff0c;有回滚和提交事务的功能。 支持行级锁定&#xff0c;提供更高的并发。 支持外键约束&#…

修改ElTable组件的样式(element-plus)

效果展示 <div class"table_main"><ElTable:data"tableList":header-cell-style"{color: #ffffff,background: #6f7f93,}"class"table_border":highlight-current-row"false"><ElTableColumn type"inde…

Java笔记(其五)--流程控制

switch switch(a) { case ***: break; ***** default: break; } 需要注意的点&#xff1a; 其中的 a 的类型&#xff0c;只支持byte、short、int、char&#xff0c;不支持double、float、long&#xff08;string也是支持的&#xff0c;这里说的是基础的数据类型&#x…

CentOS 自建gitlab仓库:安装相关工具

所需环境 Node 安装项目依赖、项目打包运行Nginx 前端项目部署&#xff08;正向代理、反向代理、负载均衡等&#xff09;Git 自动化部署时 拉取代码使用GitLab 代码仓库GitLab-Runner GitLab的CI/CD执行器 一、安装Node 检测是否已安装 常用node -v 命令检测。 如果已安装&a…

百面算法工程师目录 | 深度学习目标检测、语义分割、分类上百种面试问答技巧

本文给大家带来的百面算法工程师是深度学习面试目录大纲&#xff0c;文章内总结了常见的提问问题&#xff0c;旨在为广大学子模拟出更贴合实际的面试问答场景。在这篇文章中&#xff0c;可以点击题目直达问题答案处&#xff0c;方便查找问题寻找答案。节约大家的时间。通过对这…

Docker 快速安装指南 (CentOS 7)

Docker 快速安装指南 (CentOS 7) 1. 更新现有的软件包 sudo yum update -y2. 安装必要的依赖包 sudo yum install -y yum-utils device-mapper-persistent-data lvm2yum-utils: 提供 yum-config-manager 工具&#xff0c;方便添加软件仓库。device-mapper-persistent-data 和…

7-115 差分矩阵

知识点:差分 输入一个 n 行 m 列的整数矩阵,再输入 q 个操作,每个操作包含五个整数 x1,y1,x2,y2,c,其中 (x1,y1) 和 (x2,y2) 表示一个子矩阵的左上角坐标和右下角坐标。 每个操作都要将选中的子矩阵中的每个元素的值加上 c。 请你将进行完所有操作后的矩阵输出。 1≤n,…

ACGO欢乐赛#19题解

ACGO欢乐赛#19题解 T1、人工AI T2、判闰年 T3、一天中的某个时刻 T4、二进制下1的个数 T5、修正字符 T6、恰排骨 T7、买零食 T8、真-签到题

为什么你的企业需要微信小程序?制作微信小程序有什么好处?

什么是小程序&#xff1f; WeChat小程序作为更大的WeChat生态系统中的子应用程序。它们就像更小、更基本的应用程序&#xff0c;在更大的应用程序&#xff08;WeChat&#xff09;中运行。这些程序为用户提供了额外的高级功能&#xff0c;以便在使用WeChat服务时加以利用。根据…

sqlserver数据库查询注释/表结构的语句

sqlserver数据库和mysql查看的方式不一样&#xff0c;sqlserver需要通过语句来查&#xff0c;我们只需要替换掉语句里的表名就可以。 1查看表名&#xff0c;字段名&#xff0c;字段注释 SELECT A.name AS table_name, B.name AS column_name, C.value AS column_description F…

Docker 快速搭建 Kafka 集群

Docker 快速搭建 Kafka 集群 你是否想要一个 Kafka 集群&#xff0c;但又不想经历繁琐的手动配置过程&#xff1f;别担心&#xff0c;有了 Docker 和 Docker Compose&#xff0c;我们可以轻松快捷地搭建一个 Kafka 集群&#xff0c;让你能专注于享受实时数据流处理的乐趣。 环…

Mongodb操作与Java(三)增删改语句及DDL新增或删除字段

MongoDB概念 MongoDB 基本概念指的是学习 MongoDB 最先应该了解的词汇&#xff0c;比如 MongoDB 中的"数据库"、"集合"、"文档"这三个名词&#xff1a; 文档&#xff08;Document&#xff09;&#xff1a; 文档是 MongoDB 中最基本的数据单元&…

DeepSeek发布全新开源大模型,GPT-4级别能力 价格仅百分之一

最新国产开源MoE大模型&#xff0c;刚刚亮相就火了。 DeepSeek-V2性能达GPT-4级别&#xff0c;但开源、可免费商用、API价格仅为GPT-4-Turbo的百分之一。 因此一经发布&#xff0c;立马引发不小讨论。 从公布的性能指标来看&#xff0c;DeepSeek-V2的中文综合能力超越一众开源…

运维实施工程师之Linux服务器全套教程

一、Linux目录结构 1.1 基本介绍 Linux 的文件系统是采用级层式的树状目录结构&#xff0c;在此结构中的最上层是根目录“/”&#xff0c;然后在此目录下再创建其他的目录。 在 Linux 世界里&#xff0c;一切皆文件&#xff08;即使是一个硬件设备&#xff0c;也是使用文本来标…