在阻止对socket.recv()的调用期间正常停止套接字

时间:2019-05-30 11:51:03

标签: python sockets udp

我有一个在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),但它们都会引发错误。

1 个答案:

答案 0 :(得分:0)

因此sock.recv(1500)将阻塞直到收到某物。如果什么也没收到,那就等待。

但是,如果您设置了超时时间,那么周期性地等待将引发异常,您可以在尝试再次读取之前做其他事情(例如查看完成标志)。

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