LoginSignup
4
5

More than 3 years have passed since last update.

馬鹿の一つ覚え: Pythonでプロセス間通信

Last updated at Posted at 2019-01-22

Pythonでプロセス間通信(IPC)を行うサーバ側とクライアント側のプログラム

サーバ側にアクセスされるたびにインクリメントされた整数値を16進数の文字列として返す

サーバ側

#!/usr/bin/env python

import sys
from socket import socket, AF_INET, SOCK_STREAM

host = 'localhost'    # 同一ホスト間での通信
port = 57923    # サーバ側の受信ポート番号
port_min = 58111    # クライアント側の受信ポート番号の下限
port_max = 58999    # クライアント側の受信ポート番号の上限
max = 1024    # 通信文字列のサイズ
n_thread = 4    # スレッド数
number = 101    # 応答する数値の初期値

if len(sys.argv) > 1:
  number = int(sys.argv[1])    # 第1コマンド引数で数値の初期値を変更可

server_socket = socket(AF_INET, SOCK_STREAM)    # サーバ側受信用
server_socket.bind((host, port))
server_socket.listen(n_thread)
print("Server socket is ready.")

while True:
  try:
    (client_socket, address) = server_socket.accept()    # サーバ側受信
    message = client_socket.recv(max).decode('utf-8')    # 文字列を受信
    client_socket.close()
    print(message)
    port = int(message)    # 文字列がクライアントに返信する際のポート番号
    if port_min <= port <= port_max:
      socket_send = socket(AF_INET, SOCK_STREAM)    # サーバ側送信用
      socket_send.connect((host, port))
      message = '{:06x}'.format(number)    # 6桁の16進整数
      socket_send.send(message.encode('utf-8'))
      socket_send.close()
      number += 1    # 数値をインクリメント
      continue
  except:
    sys.stderr.write("Error 31\n")

server_socket.close()
print('Server socket is closed.')

クライアント側

#!/usr/bin/env python

import sys
import random
from socket import socket, AF_INET, SOCK_STREAM

host = 'localhost'    # 同一ホスト間での通信
port = 57923    # サーバ側の受信ポート番号
port_min = 58111    # クライアント側の受信ポート番号の下限
port_max = 58999    # クライアント側の受信ポート番号の上限
max = 1024    # 通信文字列のサイズ
n_thread = 4    # スレッド数

socket_send = socket(AF_INET, SOCK_STREAM)    # クライアント側送信用
socket_send.connect((host, port))
socket_recv = socket(AF_INET, SOCK_STREAM)    # クライアント側受信用
while True:
  port = random.randint(port_min, port_max)    # 受信ポートの番号を作成
  try:
    socket_recv.bind((host, port))
    socket_recv.listen(n_thread)
    break
  except:    # 失敗したらポート番号の作成からやり直す
    sys.stderr.write('Error 41: port ' + port + "\n")
socket_send.send(str(port).encode('utf-8')) # サーバ側に受信用ポート番号を伝えて採番を依頼
socket_send.close()
while True:
  try:
    (socket_prvd, address) = socket_recv.accept()   # 採番結果
    message = socket_prvd.recv(max).decode('utf-8') # 文字列で取得
    socket_prvd.close()
    socket_recv.close()
    sys.stderr.write(message + "\n")    # プロセス間通信で取得した文字列を表示
    break
  except:
    sys.stderr.write("Error 42\n")
4
5
1

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
5