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的数值。

相关推荐
JhonKI8 分钟前
【Linux网络】构建与优化HTTP请求处理 - HttpRequest从理解到实现
linux·网络·http
GOATLong38 分钟前
网络基础概念
linux·运维·服务器·网络·arm开发·c++
技术liul1 小时前
如何在iStoreOS DHCP中排除特定IP地址
网络·windows·tcp/ip
桃花岛主702 小时前
NAT穿透
服务器·网络·智能路由器
sky.fly2 小时前
路由器重分发(OSPF+RIP),RIP充当翻译官,OSPF充当翻译官
网络·智能路由器
sky.fly2 小时前
思科路由器重分发(静态路由+OSPF动态路由+RIP动态路由)
大数据·网络·智能路由器
网工养成记_121382 小时前
路由协议基础
网络·网络协议·智能路由器
JhonKI2 小时前
【Linux网络】Http服务优化 - 增加请求后缀、状态码描述、重定向、自动跳转及注册多功能服务
linux·网络·http
【0931】2 小时前
差错检测的学习
网络·学习
xiaoniu6673 小时前
毕业设计-基于机器学习入侵检测系统
网络·安全·web安全