ソケット通信を停止させる時にエラーが出ます。
エラーを再現するために色々試して見た結果、以下のようにsleepを挟んでデータを送っていると、受信側でソケット通信を停止させる時にエラーになるようです。
testSend.py
import time
from socket import socket, AF_INET, SOCK_DGRAM
HOST = ''
PORT = 5000
ADDRESS = "127.0.0.1"
s = socket(AF_INET, SOCK_DGRAM)
while True:
s.sendto(str(time.time()).encode(), (ADDRESS, PORT))
time.sleep(0.1)
s.close()
受信側のコードは、以下のようになっています。
GUIを立ち上げて[start]ボタンを押すとデータを受信して、200秒に1度ずつ時間をprintし
[stop]ボタンを押すと受信とprintを停止するプログラムになっています。
testRecieve.py
import tkinter as tk
import threading
import time
from socket import socket, AF_INET, SOCK_DGRAM
class threadingGUI():
def __init__(self):
self.stop_flag = True
self.s = None
self.thread1 = None
self.thread2 = None
def worker(self):
#文字列を受け取る
messages, address = self.s.recvfrom(8192)
print(messages)
def schedule(self,interval, f, wait=True):
base_time = time.time()
next_time = 0
while not self.stop_flag:#接続を切るボタンが押されるまでループ
self.thread2 = threading.Thread(target=f)
self.thread2.start()
if wait:
self.thread2.join()
next_time = ((base_time - time.time()) % interval) or interval
time.sleep(next_time)
def start(self):
if not self.thread1:
HOST = ''
PORT = 5000
#受信
ADDRESS = "127.0.0.1"
self.s = socket(AF_INET, SOCK_DGRAM)
self.s.bind((HOST, PORT))
self.thread1 = threading.Thread(target=self.schedule,args=(1.00/200.00, self.worker, False))
self.stop_flag=False
self.thread1.start()
def stop(self):
if self.thread1:
self.stop_flag=True
self.thread1.join()
self.s.close()
self.thread1=None
def GUI_start(self):
root=tk.Tk()
Button001=tk.Button(root,text="Start",command=self.start)
Button001.pack()
Button002=tk.Button(root,text="Stop",command=self.stop)
Button002.pack()
root.mainloop()
t = threadingGUI()
t.GUI_start()
[stop]ボタンを押すと
line 15, in worker
messages, address = self.s.recvfrom(8192)
OSError: [WinError 10038] ソケット以外のものに対して操作を実行しようとしました。
というエラーメッセージが繰り返し表示されます。
testSend.pyからtime.sleep(0.1)を消すとこのエラーはなくなるのですが。
このsleepを残したままエラーを出さない方法はないでしょうか?