LoginSignup
4
4

More than 5 years have passed since last update.

pythonによるネットワークの片道遅延の測定

Last updated at Posted at 2017-02-18

モチベーション

ある遅延と変動が大きい国際間通信について、往路、復路のどちらが通信に影響しているのか調べたい。PingによるRTT遅延測定ではなく、往路復路別々に測定したい。現状片道遅延が難しい理由は測定する2ノードの時間が正確に同期していなければならないため。ただ、今回のような国際回線はRTT 100msもあるので最寄りNTP同期で良しとする。せいぜい誤差数msだろうし、理論的な最短片道遅延も推測でき、そこからNTP同期ズレ値もある程度推測できると想定。
また、処理オーバーヘッドを考えると本来スクリプトで処理するべきではないけど、スクリプトにしたところで昨今のサーバなら1msも誤差を生じないだろう、ということで、楽ちんなPythonを選択。
かんたんにいうと、「ざっくり、てきとうに手抜きして」

手法

クライアント~サーバー間でupdパケット1往復
1. クライアントは(a)開始時刻を保存しサーバへパケット到着時間を問い合わせる
2. サーバは(b)そのパケットを受信した時間をクライアントへ返信
3. クライアントは(c)サーバからの返信を受信した時間を記録
4. (b) - (a) = 往路遅延 / (c) - (b) = 復路遅延

コード(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' # とりあえず自IPを指定
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()

実際はパケロスもひどいので、リトライ処理とか、タイムアウト処理も必要だし、もう少し扱いやすい出力で実装したけど、今は省略。

とりあえずローカルホストで実行

同一ホスト内(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

ping より精度が少なくとも1桁は劣る。。。主に往路のオーバーヘッドが重いなあ。まあ10μsと100μsの精度の差、だいたい想定どおり。国際回線じゃ無視していいだろ。(あきらめが肝心)

実際の国際回線での測定結果

青線:往復、オレンジ:往路、緑:復路。半日ぐらいバッチで走らせて、グラフ化して読み取れることは
1. 明らかにRTT遅延に対する往路遅延の影響はでかい
2. 地理的経路はほぼ同じ(はず)で片道15msはやや短めな気がするので、ノードの時間が最大3msぐらいずれてるかも。
3. 私は休日の早朝からなにやってるんだろう。
image

ちなみに同じデータセンタの違うインスタンスで試したら1マイクロ秒ぐらい未来の時間が帰ってきたw

追記

2017/2/26: Cで等価なコードに書いてみたけど150μs減ぐらい。思ったより改善しなかった。当面pythonでいいや。

4
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
4