【发布时间】:2016-09-21 06:10:54
【问题描述】:
我有一个“作业”服务器,它接受来自客户端的请求(有 8 个客户端从另一台机器发送请求)。服务器然后提交一个“作业”(“作业”只是一个将结果文件写入磁盘的可执行文件),并且在“作业管理器”线程上等待直到作业完成。作业完成后,它会向客户端发送一条消息,表明结果文件已准备好复制回客户端。
在主线程上,我使用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 实例访问套接字 - 如果作业完成,线程会通过相关的socket - 所以也许同一套接字的send 和recv 方法会导致某种竞争条件?但无论如何,我不明白这会如何导致“连接超时”错误。
【问题讨论】:
-
尝试在此处阅读详细信息:pymotw.com/2/select
-
@ReutSharabani,我读过它,实际上我的代码是基于它的。但是您可以在我的代码中看到,从
readbale列表中的套接字读取时引发了异常,并且您提到的链接状态为All of the sockets in the readable list have incoming data buffered and available to be read- 所以这并不能解释我遇到的问题
标签: python sockets client-server