63774


Qiitの、[Pythonで一定間隔ごとにループを回す方法](https://qiita.com/montblanc18/items/05715730d99d450fd0d3)と、[UDP通信](https://qiita.com/akakou/items/e9fbcfc0c69cc957152e)の記事を参考にしています。

以下のudpSend.pyは、0.1秒ごとにデータを送信するコードです。

**udpSend.py**

[code]

    import time
    import threading
    from socket import socket, AF_INET, SOCK_DGRAM
    
    HOST = ''
    PORT = 5000
    ADDRESS = "127.0.0.1" # 自分に送信
    
    s = socket(AF_INET, SOCK_DGRAM)
    startTime = time.time()
    
    def worker():
        try:
            msg = str(time.time()-startTime)
            s.sendto(msg.encode(), (ADDRESS, PORT))
            time.sleep(8)
        except:
            pass
    
    def scheduler(interval, f, wait = True):
        base_time = time.time()
        next_time = 0
        while True:
            t = threading.Thread(target = f)
            t.start()
            if wait:
                t.join()
            next_time = ((base_time - time.time()) % interval) or interval
            time.sleep(next_time)
    
    scheduler(0.1, worker, False)
    
[/code]

そして、以下のudpRecv.pyは1.0秒ごとにudpを受信してprintするコードになっています。

**udpRecv.py**

[code]

    import time
    import threading
    from socket import socket, AF_INET, SOCK_DGRAM
    
    HOST = ''   
    PORT = 5000
    
    # ソケットを用意
    s = socket(AF_INET, SOCK_DGRAM)
    # バインドしておく
    s.bind((HOST, PORT))
    
    def worker():
        try:
            msg, address = s.recvfrom(8192)
            print(msg.decode('utf-8'))
            time.sleep(8)
        except:
            pass
    
    def scheduler(interval, f, wait = True):
        base_time = time.time()
        next_time = 0
        while True:
            t = threading.Thread(target = f)
            t.start()
            if wait:
                t.join()
            next_time = ((base_time - time.time()) % interval) or interval
            time.sleep(next_time)
    
    scheduler(1, worker, False)
    
[/code]

送信側は0.1秒間隔なのに対し、受信側は1.0秒間隔でデータを受信させたところ  
以下のような出力結果になりました。

[code]

    10.801141023635864
    10.900874853134155
    11.001609802246094
    11.10069465637207
    11.200777292251587
    11.301504135131836
    
[/code]

udpRecv.pyによって、1秒間隔で値がprintされるのに  
printされる時間は0.1秒間隔の値になっており、ラグが発生してしまっています。

送信側の時刻と、受信側の時刻で一定以上のラグがあった場合  
その送信データは受け取らないようなことは出来ないのでしょうか？

udpRecv.pyで、1.0秒ごとの値を受け取って1.0秒ごとにをprintしたいです。


CC BY-SA 4.0
2020-03-11T11:26:23.437
63764
2020-03-11T23:15:37.820
34471
question
python network socket udp
PythonのUDP通信で更新周期の違うコードからラグなしのデータを受け取る方法


> 受信側は1.0秒間隔でデータを受信させたところ

この認識が誤っていて、「1秒間隔で受信バッファに溜まっているデータを読み出す」コードが正しい動きをしています

本当にやらないといけないことは質問からはよみとれませんが、例えば

  * 最新(もしくは必要なタイムスタンプ)のデータ以外は読み捨て
  * n + 0.9秒でバッファを捨てて0.1秒後に読み出し

などする必要があります


CC BY-SA 4.0
2020-03-11T23:15:37.820
63774
2020-03-11T23:15:37.820
5793
63764
answer