2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

pythonでsocket通信(サンプルプログラム)

Last updated at Posted at 2022-11-27

はじめに

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の形式にしています。(このあたりは、どうするのがベストプラクティスなのか不明です…)

2
1
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
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?