実現したいこと
・一台のサーバから複数台の受信機に対して同じデータを送信する
・効率の良い送信を行うため,マルチキャストを使用する
・マルチキャストを使い,複数台の受信機に対してほぼ同時にデータを配信した後,それぞれからの返信を受信する.
実装
実装環境
・本記事では自身のラップトップをサーバとし,複数台のESP32に対してデータ送信行いましたが,どんな環境でもできるはずです.
使用するライブラリ
・Threadingライブラリ
簡単に説明すると非同期処理を行うライブラリです.
実装方法
サーバから受信機であるESP32に対して,簡単な挨拶メッセージを送り,それに対して個々から返信をもらうプログラムです.おまけに受信時間を記録しています.
今回のコードでは,respond関数をメインスレッドから切り離し,受信機からの返信が到着したタイミングでrespond関数内の処理を行います.
またソケットがタイムアウト(指定秒以内に受信しない)したら,例外処理に移行し,スレッドを閉じることでプログラムが終了します.
server.py
import time
import socket
import threading
LOCALHOST = socket.gethostbyname(socket.gethostname())
multicast_grp = "239.1.2.3"
PORT = 1234
end_t = []
# ソケットを作成
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind((LOCALHOST, PORT))
sock.settimeout(4)
# クライアントからのメッセージを受信して返信する関数
def respond():
# クライアントからのデータを受信
while True:
try:
data, addr = sock.recvfrom(1024)
end = time.time()
end_t.append(end)
except Exception as e:
# タイムアウトしたらこのスレッドを終了する
print(f"error: {e}")
break
# クライアントに順番にデータを送信し、同時に受信も行うスレッドを作成して開始
start_t = time.time()
respond_thread = threading.Thread(target=respond)
respond_thread.start()
sock.sendto("Hello ESP32!".encode(), (multicast_grp, PORT))
# スレッドが終了するまで待機
respond_thread.join()
print("All Done")
※受信機側の処理は省いていますが,マルチキャストパケットを受信したらそれぞれが通常通り返信を行えばいいです.