はじめに
Docker上に展開しているコンテナでsocketで受信待ち状態にして、socketで通信を受け取ったら、以降の処理を走らせる形のサンプルプログラム。
別コンテナからのリクエストで、同期して処理を実行させたい場合などに使えるかと。
環境
- windows10 pro
- wsl2(20.04.5 LTS (Focal Fossa))
- Dockerのバージョン
- Docker version 20.10.18, build b40c2f6
- docker-compose version 1.29.2, build 5becea4c
※Docker Desktop ではありません
※通信のリクエストは、Windowsからも行っています
- python 3.10.7
- コンテナのポート設定については
ports:
- 50000:50000
を入れています
コード(受信側)
receive.py
import socket
import logging
# 受信IP(外部からの接続は127.0.0.1では、多分NGかと、、)
RCV_HOST = "0.0.0.0"
# 受信ポート
RCV_PORT = 50000
# 受信可能数(処理中に同時受信数が指定を超えると、待ちが発生せずに処理終了??)
BACKLOG = 10
# 一度の通信受信できる最大データバイト数
BUFSIZE = 1024
# ログ出力設定
logging.basicConfig(
level=logging.DEBUG, filename="recive.log", format="rcv_msg: %(message)s"
)
# ソケット定義
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sct:
# 再使用設定(3つ目の引数が、考え方間違っているかも)
sct.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, BUFSIZE)
# 受信設定
sct.bind((RCV_HOST, RCV_PORT))
sct.listen(BACKLOG)
# 継続受信のため、永久ループ
while True:
# コネクション定義(切断処理の判定対策)
conn = None
try:
# 受信の待機
(conn, addr) = sct.accept()
# 通信内容を受信
rcv_msg = conn.recv(BUFSIZE)
# 受信内容のログ出力
logging.debug(rcv_msg.decode())
# 送信側に値を返す
conn.send(b"recived:" + rcv_msg)
finally:
# 受信せずに終わる場合(ctrl+c等)は、処理を抜けさせる
if conn is None:
break
# コネクションを閉じる
conn.close()
コード(送信側)
send.py
import socket
# 接続IP
CONNETC_HOST = "127.0.0.1"
# 接続ポート
CONNECT_PORT = 50000
# 送信内容
BUFSIZE = 1024
# 送信内容
SEND_DATA = b"send message"
# ソケット定義
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sct:
# 接続
sct.connect((CONNETC_HOST, CONNECT_PORT))
# メッセージ送信
sct.send(SEND_DATA)
# 受信内容の取得
rcv_message = sct.recv(BUFSIZE).decode()
# 受信内容の確認
print(rcv_message)
確認方法(不要でしょうが、、)
- 受信側
直接実行
python receive.py
or
バックグラウンド実行(nohup.outを出力しない)
nohup python receive.py > /dev/null 2>&1 &
- 送信側
python send.py
おまけ
バックグランド実行を終了させるときは
ps -ef |grep receive.py
でreceive.pyを実行しているPIDをみつけて(下記のような結果のときは90がPID)
pyuser 90 7 0 04:43 pts/1 00:00:00 python receive.py
pyuser 92 7 0 04:43 pts/1 00:00:00 grep receive.py
-2
を指定して、killコマンドを実行する(バックグラウンド実行のものを、ctrl+cで終了させるようなイメージ)
kill -2 {PID}
# 例)kill -2 90
最後に
一部、引数の解釈が間違っていたりする可能性はありますが、基本的には問題なく動くと思います。
コネクションもwith構成にしたかったのですが、受信待ちのときに終了すると、エラーになってしまい、後続の処理が実行されないみたいなので、try/exceptの形式にしています。(このあたりは、どうするのがベストプラクティスなのか不明です…)