您的位置:首页 > 其它

关于 socket.recv 阻塞问题

2010-01-22 11:54 274 查看
在开发中遇到个问题。

标准的socket 客户端应该是这样的~_~ 我见网上书上都这样写。所以我说是“标准的”

# -*- coding: utf-8 -*-
import socket,time

host = "127.0.0.1"
port = 9009

s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect((host,port))

s.send("SELECT * FROM tt")
a = s.recv(655350)
print a
s.close()


客户端在 recv 服务端发送来的数据后,就直接 close socket 了。这样的确是没问题

但我在想,如果服务端一次发送的数据量很大很大~~ 超出了 recv(指定的bufsize) 那么一次接收不是有问题了吗?所以我改成了循环接收方式

# -*- coding: utf-8 -*-
import socket,time

host = "127.0.0.1"
port = 9009

s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect((host,port))

s.send("SELECT * FROM tt")
while True:
a = s.recv(1024)
if not len(a):break
print a
s.close()


的确。一样能接收,但这样的问题是。 recv 是阻塞的。也就是会一直等待服务端发送来的数据包。如果没有数据包到来,就一直会等待。

也就是后面的 if not len(a):break 无效,也就退不出循环。这个也是不符合我的需求的。 第一想到如何能让 recv 不阻塞了。通过查看手册发现两个办法

1 。 socket.setblocking(0)

2. 使用 socket.MSG_DONTWAIT 这个我们可以通过 man recv 来查看说明

但这样以后,还是有问题~,问题就是,recv不阻塞了。在 send 数据出去后,服务端还来没来得急返回数据,客户端已经跑到了recv这里,而又不阻塞。所以抛出了一个异常。这个在手册上有说明

Set blocking or non-blocking mode of the socket: if flag is 0, the socket is set to non-blocking, else to blocking mode. Initially all sockets are in blocking mode. In non-blocking mode, if a recv() call doesn’t find any data, or if a send() call can’t immediately dispose of the data, a error exception is raised;

可以在recv前加一个time.sleep(2)模拟一个阻塞就可以看到这个事实。加了 sleep 以后,recv就可以等到服务端返回的数据,顺利的在不阻塞的状态下执行下去了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐