>我有一个在 2 个线程上运行的程序。主线程用于自己的工作,另一个线程在 UDP 套接字上不断调用recv()
。
基本上,代码结构如下所示:
done = False
def run_sock():
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(('localhost', 12345))
while not done: # receive data until work done
data = sock.recv(1500)
print(data)
sock.close()
thread = threading.Thread(target=run_sock, daemon=True)
thread.start()
# Main thread
while not done:
... # Do work here
if some_condition: # Stop running, thread should as well
done = True
thread.join()
我想在主线程done
更改为True
时关闭套接字,但是当发生这种情况时,套接字仍处于当前阻塞recv
调用状态,并且必须在最终停止之前接收另一条消息。
有没有办法优雅地关闭套接字(无需处理错误(?我试过sock.shutdown(socket.SHUT_RDWR)
,sock.setblocking(False)
,但它们都会引起错误。
所以sock.recv(1500)
会阻止,直到它收到一些东西。如果它什么也没收到,那么它就会等待。
但是,如果您设置了超时,那么该等待会定期抛出异常,您可以在尝试再次读取之前执行其他操作(例如查看 done 标志(。
sock.settimeout(1.0)
sock.bind(...)
while not done:
try:
data = sock.recv(1500)
except timeout:
continue
sock.close()
当然,如果远程端关闭了连接,那是不同的。然后你需要查看data
,看看它是否为空。
while not done:
try:
data = sock.recv(1500)
if not data:
break
except timeout:
continue