可读的套接字在recv上超时

时间:2016-09-21 06:10:55

标签: python sockets client-server

我有一份工作'接受来自客户端的请求的服务器(有8个客户端从另一台机器发送请求)。然后,服务器提交一份“工作”作业。 (一个' job'只是一个将结果文件写入磁盘的可执行文件),以及一个' job manager'线程等待工作完成。作业完成后,它会向客户端发送一条消息,表明结果文件已准备好复制回客户端。

在主线程上,我使用select来读取来自客户端的传入连接以及作业请求:

readable, writable, exceptional = select.select(inputs, [], [])

其中inputs是已接受连接(套接字)的列表,此列表还包含server套接字。所有套接字都设置为非阻塞。据我所知,如果对select的此调用返回非空readable,则表示inputs的某些元素有等待读取的传入数据。 我正在使用以下逻辑读取数据(SIZE是常量):

for s in readable:
    if s is not server:
        try:
            socket_ok = True
            data = s.recv(SIZE)
        except socket.error as e:        
            print ('ERROR socket error: ' + str(e) )
            socket_ok = False
        except Exception as e:
            print ('ERROR error reading from socket: ' + str(e))
            socket_ok = False
        if not socket_ok:
            # do something

我有两个问题:

  • 有时我会遇到[Errno 110] Connection timed out例外情况,而且我不明白为什么 - 如果我有一个可读的套接字,那是不是意味着它有一些数据需要读取?
  • 如何处理此异常 - #do something部分。我可以做一个清理工作。 - 删除超时套接字请求的正在运行的作业,并从列表中删除死套接字。但我无法让客户知道它应该停止等待这些工作。结果。理想情况下,我想以某种方式重新连接,因为工作本身会继续运行并产生我不想丢弃的结果。

编辑我现在意识到作业管理器线程也可以通过Queue实例访问套接字 - 如果作业完成,则线程发送作业& #39;通过相关套接字的消息 - 所以同一套接字的sendrecv方法可能导致某种竞争条件?但无论如何,我不知道这是如何导致连接超时的。错误。

1 个答案:

答案 0 :(得分:0)

一个只是猜测并且似乎有效的解决方案:在客户端,我使用阻塞recv方法从服务器获取作业完成的消息。由于作业可能需要很长时间(例如,如果运行作业的集群资源不足),我猜测套接字等待可能是导致超时的原因。因此,我不是在阻塞模式下使用recv,而是在超时5秒内使用它,因此我可以每隔5秒向服务器发送一条虚拟消息,以保持连接活动,直到收到消息。现在我不再得到异常(在服务器端)。