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服务端

c 复制代码
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客户端

c 复制代码
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

shell 复制代码
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

shell 复制代码
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的数值。

相关推荐
网络安全-杰克1 小时前
网络安全概论
网络·web安全·php
怀澈1221 小时前
高性能服务器模型之Reactor(单线程版本)
linux·服务器·网络·c++
耗同学一米八1 小时前
2024 年河北省职业院校技能大赛网络建设与运维赛项样题二
运维·网络·mariadb
skywalk81631 小时前
树莓派2 安装raspberry os 并修改成固定ip
linux·服务器·网络·debian·树莓派·raspberry
C++忠实粉丝2 小时前
计算机网络socket编程(3)_UDP网络编程实现简单聊天室
linux·网络·c++·网络协议·计算机网络·udp
黑客Ela2 小时前
网络安全中常用浏览器插件、拓展
网络·安全·web安全·网络安全·php
qdprobot2 小时前
ESP32桌面天气摆件加文心一言AI大模型对话Mixly图形化编程STEAM创客教育
网络·人工智能·百度·文心一言·arduino
hakesashou4 小时前
Python中常用的函数介绍
java·网络·python
C++忠实粉丝4 小时前
计算机网络socket编程(4)_TCP socket API 详解
网络·数据结构·c++·网络协议·tcp/ip·计算机网络·算法
九州ip动态4 小时前
做网络推广及游戏注册为什么要换IP
网络·tcp/ip·游戏