主に自分用のメモです。
はじめに
- Pythonでメインのプログラムの傍らUDP通信をしたい
- マルチスレッドで通信内容を共有したい
ということで複数スレッドを立てて,片方のスレッドでUDPを受信しつつもう片方のスレッドで別の作業をできるようにします。
参考にしたページ群を以下に追記していきます。
マルチスレッド
簡単なマルチスレッドでよければPythonのthreadingを用います。
- https://qiita.com/komorin0521/items/c25cfcff89c0b1afe882
- https://qiita.com/castaneai/items/9cc33817419896667f34
UDP通信
以下の記事をソケット通信実装の参考にしました。
-
UDPとTCPの詳しい違いに関して:記事
UDP通信とマルチスレッドに関する記事はTCPで通信しており,UDPに変える必要がありますね。
UDP クライアント
標準入力から入力を取得して送信するクライアントのプログラムをかきました。
client.py
# coding: utf-8
from socket import *
HOST = gethostname()
PORT = 34512
BUFSIZE = 1024
ADDR = (gethostbyname(HOST), PORT)
USER = 'Client'
udpClntSock = socket(AF_INET, SOCK_DGRAM)
while True:
data = input('%s > ' % USER) # 標準入力からのデータ入力
udpClntSock.sendto(data.encode('utf-8'), ADDR) # データ送信
#udpClntSock.setblocking(0)# Non blocking
if not data:
break
udpClntSock.close()
UDPなのでソケットを作ってぶち込むだけです。
サーバー側
サーバー側では別のスレッドを立ててそこで受信を待ちつつ,main関数で受信した文字列を閲覧しています。
グローバル変数でも良いらしいですが,クラス変数を参照することによってわかりやすくなっています。
自分的ポイントは
- クラスの定義でThreadを継承
- 受信データをクラス変数に格納してmainで読めば良い
ってとこでしょうか。
import threading
import time
from socket import *
class ServerThread(threading.Thread):
def __init__(self, PORT=34512):
threading.Thread.__init__(self)
self.data = 'hoge'
self.kill_flag = False
# line information
self.HOST = gethostname()
self.PORT = PORT
self.BUFSIZE = 1024
self.ADDR = (gethostbyname(self.HOST), self.PORT)
# bind
self.udpServSock = socket(AF_INET, SOCK_DGRAM)
self.udpServSock.bind(self.ADDR) # HOST, PORTでbinding
def run(self):
while True:
try:
data, self.addr = self.udpServSock.recvfrom(self.BUFSIZE) # データ受信
self.data = data.decode()
except:
pass
if __name__ == '__main__':
th = ServerThread()
th.setDaemon(True)
th.start()
while True:
if not th.data:
break
print(th.data)
time.sleep(0.1)
UDPサーバー
非同期通信を行ったブログが参考になります。
メモなど
strとbyte型の変換
Python3ではソケットを送る際にstr型からbyte型への変換を求められます。
str型はともかく,byte型とはb'hogefuga'
で表される文字列で,''の前にbを入れればOKです。
また,encodeとdecodeで変換できます。
>>> 'hogefuga'.encode('utf-8')
b'hogefuga'
>>> b'hogefuga'.decode('utf-8')
'hogefuga'
このutf-8
を入力しないでも一応変換してくれますがデフォルトの変換がどのようなものかわからないので一応入れておくようにしましょう。
非同期通信を用いる
マルチスレッドの他にもノンブロッキングプロセスという仕組みを用いて通信待ちをしながら別の処理ができます。
気が向いたら追記します(PCの電池が切れそう)