プログラム間通信をするための勉強メモ.

socket プログラムの練習で簡単なチャット(もどき)をするためのプログラムを作ったが,会話のキャッチボールをしなければいけなかった.
つまり,一回メッセージを受信したら一回メッセージを送信する,ということの繰り返しであった.
逆に言うと,メッセージを続けて2回以上送信(あるいは受信)できなかった.

これは recv() がメッセージを受信するまで待ち状態になるため,他のことができないためである.
送信するためのメッセージを入力するための raw_input() も,キーボードからの入力を待つので入力が完了するまで他のことができない.

この点を何とかしなければならない.

これは fork を使ってマルチプロセスにすることで対応できる.
一方のプロセスが recv() で待ち状態で止まっている間,他方のプロセスは別のことができる.

前回のエントリーにメモしたように fork についても例題で動作を確認した.

これらを組み合わせてみる.

=== Server === === Client ===
import os
import sys
from socket import *

HOST = ''
PORT = 50007

s = socket(AF_INET, SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
(conn, addr) = s.accept()

print 'Connected by', addr

pid = os.fork()

if pid == 0:
print "child process"
while 1:
msg = raw_input("> ")
conn.send('%s' % msg )
if msg == ".":
break;
sys.exit()

else:
print "parent process"
while 1:
data = conn.recv(1024)

if not data:
print 'End'
break
elif data == ".":
print "Client is closed"
os.kill(pid, 9)
break

print "S Data receive: ", data

conn.close()
sys.exit()
 
import os
import sys
from socket import *

HOST = ''
PORT = 50007

s = socket(AF_INET, SOCK_STREAM)
s.connect((HOST, PORT))

pid = os.fork()

if pid == 0:
print "child process"
while 1:
msg = raw_input("> ")
s.send('%s' % msg )
if msg == ".":
break
sys.exit()

else:
print "parent process"
while 1:
data = s.recv(1024)

if not data:
print 'End'
break
elif data == ".":
print "Server is closed"
os.kill(pid, 9)
break

print "C Data receive: ", data

s.close()
sys.exit()


サーバーもクライアントも,親プロセスでメッセージを受けて,子プロセスでメッセージを送信する.
親がメッセージ受信待機中でも子プロセスで何度でもメッセージの送信を行うことができる.
"." を入力すると,その子プロセスは終了する."." を受け取った側のサーバーは,その側の子プロセスを閉じて,自分も終了する.この終了により相手側のサーバーも "End" を表示して終了する.


実行結果は以下のようになる.

=== Server === === Client ===
6:37.amarone[11883]python server.py    
Connected by ('127.0.0.1', 53185)
parent process
child process
> S Data receive: hello
S Data receive: how are you?
S Data receive: are you fine?

> I'm fine
> bye
> .
End
 
6:37.amarone[11882]python client.py
parent process
child process
> hello
> how are you?
> are you fine?
> C Data receive: I'm fine
C Data receive: bye
Server is closed

これで,socket と fork を用いて chat のようなことができた.




やじるし プログラム間通信関連メモの目次