关于socket.recv()阻赛问题

[原文地址]   http://blog.csdn.net/huithe/article/details/5223785


在开发中遇到个问题。

 

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

 

[python] view plain copy
  1. # -*- coding: utf-8 -*-  
  2. import socket,time  
  3.   
  4. host = "127.0.0.1"  
  5. port = 9009  
  6.   
  7. s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)  
  8. s.connect((host,port))  
  9.   
  10. s.send("SELECT * FROM tt")  
  11. a = s.recv(655350)  
  12. print a  
  13. s.close()  

 

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

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

 

 

[python] view plain copy
  1. # -*- coding: utf-8 -*-  
  2. import socket,time  
  3.   
  4. host = "127.0.0.1"  
  5. port = 9009  
  6.   
  7. s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)  
  8. s.connect((host,port))  
  9.   
  10. s.send("SELECT * FROM tt")  
  11. while True:  
  12.     a = s.recv(1024)  
  13.     if not len(a):break  
  14. print a  
  15. 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就可以等到服务端返回的数据,顺利的在不阻塞的状态下执行下去了
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值