关于 socket.recv 阻塞问题

本文探讨了标准Socket客户端在处理大数据量时的问题,并提出了循环接收数据的方法。然而,该方法存在阻塞和退出循环困难等问题。文章进一步讨论了解决方案,包括设置非阻塞模式及使用延时等待。

在开发中遇到个问题。

标准的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就可以等到服务端返回的数据,顺利的在不阻塞的状态下执行下去了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值