前提・実現したいこと
クライアントであるラズパイ2台(A,B)と、PC間で通信をさせています。
A、Bそれぞれは、PCからのプログラムスタートの指示(文字列'start')を受け、ある処理をした後に処理終了の時刻を示す文字列(sc_time)をPCへ送信します。
PCは、A、Bから受けた2つの時刻の差(del_sec)が5秒以下であれば、その2つの時刻を表示する。もし一方から処理終了を受けてから5秒を超えると、もう一方からの連絡を受けることなく両者にプログラム再スタートの指示を出すということをさせたいです。
発生している問題・エラーメッセージ
両者からの連絡の差が5秒以内のときは予定通り動作するのですが、再スタートの指示を出すときにプログラムが止まったままになってしまいます。
具体的には、Aから連絡を受けたのち5秒経ったので、両者に再スタートの指示を出す段階で、'Order to Rpi:sc-a start' は表示されますが 'Order to Rpi:sc-b start' がいつまで経っても表示されません。つまり、プログラムが order_to_client_sock(host_address, host_port_for_b, 'start') で止まってしまいます。
該当のソースコード
Python3
1サーバー側 2 3import threading 4import datetime 5import logging 6import time 7import socket 8 9def order_to_client_sock(host_address, host_port, message): 10 backlog = 1 11 with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: 12 s.bind((host_address, host_port)) 13 s.listen(backlog) 14 conn, addr = s.accept() 15 # クライアントにメッセージを送る 16 message_bytes = message.encode('utf-8') #文字列をバイト型に変換 17 conn.sendall(message_bytes) 18 19def receive_stamp_by_sock(timeout, host_address, host_port): 20 stamp_str = b'' 21 try: 22 with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: 23 backlog = 1 24 s.bind((host_address, host_port)) 25 s.listen(backlog) 26 s.settimeout(timeout) 27 conn, addr = s.accept() 28 29 ## クライアントから文字列を受ける 30 stamp_bytes = conn.recv(1024) 31 #バイト型を文字列変数に変換 32 stamp_str = stamp_bytes.rstrip().decode("UTF-8") 33 except socket.timeout: 34 s.close() 35 return stamp_str 36 37def receive_sc_time_sock(host_address, host_port): 38 logging.debug('start') 39 global STOP_FLAG 40 global SC_TIME_LIST 41 sc_time = '' 42 43 while len(sc_time) == 0: 44 sc_time = receive_stamp_by_sock(1, host_address, host_port) 45 logging.debug(datetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S")) 46 if STOP_FLAG == True: 47 break 48 SC_TIME_LIST.append(sc_time) 49 logging.debug('end') 50 51if __name__=='__main__': 52 check_flag = True 53 host_address = '192.168.137.1' 54 host_port_for_a = 50007 55 host_port_for_b = 50008 56 del_sec = 5 57 58 while True: 59 #端末A,Bへプログラムスタートを指示する'start'を送信 60 order_to_client_sock(host_address, host_port_for_a, 'start') 61 logging.debug('Order to Rpi:sc-a start') 62 order_to_client_sock(host_address, host_port_for_b, 'start') 63 logging.debug('Order to Rpi:sc-b start') 64 65 SC_TIME_LIST = [] 66 STOP_FLAG = False 67 check_flag = True 68 69 #端末A,Bから信号が受信されるのを待つ 70 thread_obj_a = threading.Thread( 71 target=receive_sc_time_sock, 72 args=(host_address, host_port_for_a)) 73 thread_obj_b = threading.Thread( 74 target=receive_sc_time_sock, 75 args=(host_address, host_port_for_b)) 76 thread_obj_a.start() 77 thread_obj_b.start() 78 79 while len(SC_TIME_LIST) == 0: 80 time.sleep(0.1) 81 signal_time1 = datetime.datetime.now() #第一信号 取得時刻 82 83 while not len(SC_TIME_LIST) == 2: 84 check_time = datetime.datetime.now() #第二信号 取得時刻 85 86 if check_time > signal_time1 + datetime.timedelta(seconds=del_sec): 87 check_flag = False 88 STOP_FLAG = True 89 thread_obj_a.join() 90 thread_obj_b.join() 91 logging.debug('Both threads end') 92 break 93 else: 94 continue 95 if not check_flag == False: 96 break 97 print(SC_TIME_LIST) 98 99 100クライアント側 101 省略
試したこと
タイムアウトの設定やソケットを閉じる動作に問題があるのではないかと試行錯誤してみましたが、解決に至りませんでした。
補足情報(FW/ツールのバージョンなど)
PC側、ラズパイ側ともにPython3.5
回答2件
あなたの回答
tips
プレビュー