2015-05-21 39 views
0

我正试图阻止recv等待无尽的输入。如果没有可用的数据,请从插座停止recv

首先我想:

recv = bytes('','UTF-8') 

while True: 
    data_recv = self.socketclient.recv(1024*768) 
    if not data_recv: 
     break 

    else: 
     recv += data_recv 

return recv 

在Serverside集团给我寄了照片,然后服务器host.sendall(串)后,只是等待。 所以我想了几次接收后(因为图片更大,客户端必须更频繁地接收),它会检测data_recv == false并停止,但不会发生。

我的第二个尝试是使用select()

do_read = False 
recv = bytes('','UTF-8') 

while True: 
    read_sockets,write_sockets,error_sockets = select.select([self.socketclient],[],[]) 
    do_read = bool(read_sockets) 
    print (do_read) 
    if do_read: 
     print ("read") 
     data_recv = self.socketclient.recv(640*480) 
     recv += data_recv 
    else: 
     break 

return recv 

有了这个,他只读取打印(do_read)真然后还只是停止和无休止等待。在这里,我也希望在某个时候读取False。

所以我的问题是我如何管理它,我的客户端从套接字读取整个字符串,如果没有发送了,它会停止?

我用self.socketclient.settimeout()取得了一些成功,但我宁愿不使用它,因为它总是浪费时间在程序中,它更像是一种解决方法。

回答

1

当收到所有数据时,您必须停止while循环。因此,在每次recv之后,您必须检查接收的数据长度是否是您请求的文件的长度。如果是这样,那么你打破循环,用这些数据做一些事情。

recv不知道数据发送是否完成,因为它不知道数据有多长。它只是一直听,直到你或其他端点关闭连接。

您还可以使用非阻塞套接字(这是更好的方式)。

+0

好吧,所以也许我不明白select()做了什么。我认为,如果我的套接字中有数据,它将返回true,否则它将返回false。所以如果所有的数据都已经发送完毕,'bool(read_sockets)'将在下一步返回false,然后通过制动命令退出while循环。这不是它的工作原理吗? – Mirco

+0

如果收到数据,选择返回数据,如果没有数据等待,直到收到数据,但只有阻塞套接字。如果您将使用非阻塞套接字,它将不会返回应该评估为False的数据。要切换到非阻塞套接字,请将'0'作为超时。 –

+0

这似乎并不奏效。我已经尝试过'self.socketclient.setblocking(0)'和'self.socketclient.settimeout(0)'。我还将发送图像的主机端置于睡眠状态,以确保它不会发送更多数据。但是,我的接收方仍然不会意识到发送结束,并且不会离开循环。 – Mirco