在阻止对 socket.recv() 的调用期间优雅地停止套接字



>我有一个在 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

最新更新