[LINUX] Measuring network one-way delay with python

motivation

For international communications with large delays and fluctuations, I would like to find out whether the outbound or inbound journey affects the communications. I want to measure the outbound and inbound routes separately, not the RTT delay measurement by Ping. Currently, the reason why one-way delay is difficult is that the time of the two nodes to be measured must be accurately synchronized. However, since the international line like this time has RTT 100ms, the nearest NTP synchronization is good. It is assumed that the error is several ms at most, the theoretical shortest one-way delay can be estimated, and the NTP synchronization deviation value can be estimated to some extent from it. Also, considering the processing overhead, it should not be processed by a script, but if it is a script, it will not cause an error of 1 ms with a recent server, so I chose easy Python. To put it simply, "Roughly, cut it out"

Method

1 round trip upd packet between client and server

  1. The client (a) saves the start time and queries the server for the packet arrival time.
  2. The server (b) returns the time when the packet was received to the client.
  3. The client (c) records the time it received the reply from the server.
  4. (b)-(a) = Outbound delay / (c)-(b) = Inbound delay

Code (minimum)

Server

owpingserver.py


#!/usr/bin/env python

import socket
import time

host = '0.0.0.0'
port = 12345
bufsize = 512

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind((host,port))
while True:
   data,addr = sock.recvfrom(bufsize)
   sock.sendto("%.6f" % time.time(), addr)

Client

owpingclient.py


#!/usr/bin/env python

import socket
import time

host = 'localhost' #Specify your own IP for the time being
port = 12345
bufsize = 512

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
stime = "%.6f" % time.time()
sock.sendto(stime, (socket.gethostbyname(host), port))
data, addr = sock.recvfrom(bufsize)
etime = "%.6f" % time.time()

print  "forward : " + str(float(data) - float(stime))
print  "backward: " + str(float(etime) - float(data))
print  "total:    " + str(float(etime) - float(stime))

time.sleep(1)
sock.close()

Actually, Pakeros is also terrible, so retry processing and timeout processing are required, and I implemented it with output that is a little easier to handle, but I omitted it now.

Run on localhost for the time being

Conducted within the same host (localhost)

$ python owpingserver.py &
$ python owpingclient.py
forward : 0.000324964523315
backward: 4.81605529785e-05
total:    0.000373125076294

$ ping localhost -c 1
PING localhost (127.0.0.1) 56(84) bytes of data.
64 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=0.017 ms

--- localhost ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.017/0.017/0.017/0.000 ms

It is at least an order of magnitude less accurate than ping. .. .. The overhead of the outbound route is mainly heavy. Well, the difference in accuracy between 10 μs and 100 μs is almost as expected. You can ignore it on international lines. (Giving up is important)

Measurement results on actual international lines

Blue line: round trip, orange: outbound, green: inbound. You can run it in batch for about half a day and read it as a graph

  1. Obviously the effect of outbound delay on RTT delay is huge
  2. The geographical route is (should) be almost the same, and I feel that 15ms one way is a little short, so the node time may be off by up to 3ms.
  3. What have I been doing since the early morning of the holidays? image

By the way, when I tried it on different instances in the same data center, the future time came back about 1 microsecond.

Postscript

2017/2/26: I wrote the equivalent code in C, but it decreased by about 150μs. It didn't improve as much as I expected. For the time being, python is fine.

Recommended Posts

Measuring network one-way delay with python
Network programming with Python Scapy
Neural network with OpenCV 3 and Python 3
3. Natural language processing with Python 2-1. Co-occurrence network
FizzBuzz with Python3
Scraping with Python
Statistics with python
Scraping with Python
Python with Go
Twilio with Python
Integrate with Python
Play with 2016-Python
AES256 with python
Tested with Python
python starts with ()
with syntax (Python)
Bingo with python
Zundokokiyoshi with python
Excel with Python
Microcomputer with Python
Cast with python
3. Natural language processing with Python 2-2. Co-occurrence network [mecab-ipadic-NEologd]
Load the network modeled with Rhinoceros in Python ③
Load the network modeled with Rhinoceros in Python ②
Load the network modeled with Rhinoceros in Python ①
Template network config generation with Python and Jinja2
Serial communication with Python
Zip, unzip with python
Primality test with Python
Python with eclipse + PyDev.
Socket communication with Python
Data analysis with python 2
Scraping with Python (preparation)
Try scraping with Python.
Sequential search with Python
"Object-oriented" learning with python
Run Python with VBA
Solve AtCoder 167 with python
Serial communication with python
[Python] Use JSON with Python
Learn Python with ChemTHEATER
Run prepDE.py with python3
Collecting tweets with Python
3. 3. AI programming with Python
Kernel Method with Python
Non-blocking with Python + uWSGI
Scraping with Python + PhantomJS
Try implementing associative memory with Hopfield network in Python
Posting tweets with python
Drive WebDriver with python
Use mecab with Python3
[Python] Redirect with CGIHTTPServer
Voice analysis with python
Think yaml with python
Operate Kinesis with Python
Getting Started with Python
Use DynamoDB with Python
Zundko getter with python
Handle Excel with python
Ohm's Law with Python
Primality test with python