buf = 8192
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(('192.168.1.10', 2000))
sock.sendall(data)
data = sock.recv(buf)
sock.close()
上面是最简单的socket连接程序,网上很多例子也是这样,但是recv这个地方如果服务器突然不响应了会产生阻塞,避免的办法网上大概有以下几个:
1. socket.settimeout() ,这个无法避免阻塞的,行不通
2. socket.setblocking(0) 这个必须再加个time.sleep(5)模拟阻塞,此方法兼容性很不友好。
想请问大家有什么特别好的方法没?比如异步的写法,给个示例也行。
1
est 2015 年 6 月 16 日 via Android
tornado, gevent, asyncio
|
2
binux 2015 年 6 月 16 日
select
|
3
fangjinmin 2015 年 6 月 16 日
用epoll
|
4
lilydjwg 2015 年 6 月 16 日
@binux @fangjinmin 这两个都无法解决 recv(2) 阻塞的问题——除非把套接字设置成非阻塞。
不知道你的「无法避免阻塞」是什么意思。settimeout 会在你指定的时间之后返回的,并不会一直阻塞下去啊。你一刻也不想阻塞?可 setblocking(False) 之后,你为什么还要 sleep 呢,按之前的逻辑,这样不就「阻塞」了吗?——所以,你的需求到底是什么? |
5
lilydjwg 2015 年 6 月 16 日 |
7
hualuogeng 2015 年 6 月 16 日
@lilydjwg 多好的XY
|
8
stillness 2015 年 6 月 16 日
@binux 有可能,linux 的 man select 有这么一段话
Under Linux, select() may report a socket file descriptor as "ready for reading", while nevertheless a subsequent read blocks. This could for example happen when data has arrived but upon examination has wrong checksum and is discarded. There may be other circumstances in which a file descriptor is spuriously reported as ready. Thus it may be safer to use O_NONBLOCK on sockets that should not block. |
9
way2exluren 2015 年 6 月 16 日
python 的socket在设置timeout后。
sock.timeout(5) socket就变成非阻塞socket了…… 楼主注意 |
10
zeayes 2015 年 6 月 17 日
setblocking或者settimeout,然后catch住特定的异常处理掉,就好了。
|
11
feisan 2015 年 6 月 17 日
|