表題の通り。Pythonでソケット通信をする場合はsocket.socketを使用する。TCP通信を行う場合は、一方をLISTENにして、もう一方からconnectで接続してから通信を行う。(UDPの場合は接続なしでデータを送受信すればいい。)作ったクラスは以下の通り。
from socket import * import threading class TCPboth(): def __init__(self, port, ip="127.0.0.1", timeout=3): SrcIP = ip # 受信元IP SrcPort = port # 受信元ポート番号 self.SrcAddr = (SrcIP, SrcPort) # アドレスをtupleに格納 self.BUFSIZE = 4096 # バッファサイズ指定 self.conn = None self.flg = True self.timeout = timeout def start_server(self): # サーバを起動する self.th = threading.Thread(target=self._server_th) self.th.start() def _server_th(self): if self.conn is None: self.server = create_server(self.SrcAddr) self.server.listen() # 接続を待機 self.conn, self.addr = self.server.accept() # タイムアウトを設定 self.conn.settimeout(self.timeout) while self.flg: try: s = self.conn.recv(self.BUFSIZE) self.OnRecv(s) except timeout: pass except: # タイムアウト以外の例外なら接続を閉じる self.flg = False self.conn.close() self.conn = None print("server closed") def create_connection(self, port, ip="127.0.0.1"): # 接続する if self.conn is not None: self.conn.close() self.conn = None self.conn = socket(AF_INET, SOCK_STREAM) self.conn.bind(self.SrcAddr) self.conn.connect((ip, port)) def OnRecv(self, s): # データ受信時の処理 print(s) def send(self, s): # データの送信 if self.conn is not None: self.conn.send(s.encode("UTF-8")) else: print("No connection!!") def close(self): self.flg = False if self.conn is not None: self.conn.close() self.th.join()
使用方法は以下のような感じ。まずコンソールを開き、接続を待機するサーバーを以下のように立てる。">>"のプロンプトが表示されるが、まだ接続していないのでデータは送信できない。
print("start") s1 = TCPboth(9000) s1.start_server() st = "" while st != "end": st = input(">>") s1.send(st) s1.close() print("OK") del s1
次に別のコンソールを起動し、以下のように別のサーバーを立てる。先ほどと異なる点としては、create_connectionで先ほど立てた9000番のサーバーに接続している。start_serverではすでに接続完了しているので、データの受信待ちに移行する。
print("start") s2 = TCPboth(9001) s2.create_connection(9000) s2.start_server() st = "" while st != "end": st = input(">>") s2.send(st) s2.close() print("OK") del s2
どちらのプロンプトも開けたら、好きなほうに文字を入力してエンターを押すと、もう一方に文字が出力される。データ受信時に出力だけでなくもっといろんな処理をしたい場合は、OnRecvに独自の処理を実装すればOK。