废话不说,看代码和结果
这个是服务器端的
-
# server_p.py
-
import socket, select
-
-
s = socket.socket()
-
host = socket.gethostname()
-
port = 1234
-
s.bind((host, port))
-
s.setblocking(False)
-
fdmap = {s.fileno():s}
-
-
s.listen(5)
-
p = select.poll()
-
p.register(s)
-
while True:
-
events = p.poll()
-
print 'this is out of evennt.............'
-
for fd, event in events:
-
if fd in fdmap:
-
print 'this is the accept()'
-
try:
-
c, addr = s.accept()
-
print 'Got connection from', addr
-
print 'after accept'
-
p.register(c)
-
fdmap[c.fileno()] = c
-
try:
-
data = c.recv(1024)
-
print data
-
except Exception, e:
-
print 'this is the except:', e
-
except Exception, e:
-
print 'this is the exception:', e
-
-
-
elif event & select.POLLIN:
-
print 'this is the event'
-
data = fdmap[fd].recv(1024)
-
if not data:
-
print fdmap[fd].getpeername(), 'disconnected'
-
p.unregister(fd)
-
del fdmap[fd]
-
else:
-
print data
客户端,客户端很简单,也可以直接用telnet实现同样的功能:
-
# client.py
-
import socket, time
-
s = socket.socket()
-
host = socket.gethostname()
-
port = 1234
-
s.connect((host,port))
-
s.send('this is the client')
-
time.sleep(5)
-
s.send('hahah----------------------------')
-
s.close()
诡异的结果啊,
结果就是,服务器(客户端没啥好说的,不作说明,都指服务器),p.poll()不会阻塞啊,而且不管有没有连接都会进入里面的循环中,这意味着events竟然一直有东西,我去啊啊,这是怎么回事,好吧,先澄清一点,就是,这里的server是有问题的,elif分支完全不会进去,前面if fd in fdmap感觉一点用逗没有,不如换为if fdmap[fd] is s,即判断该事件的socket是不是正在被监听的socket,从而判断是有连接请求过来,还是其他已经建立好的连接有消息发过来。这里太诡异了
来份正常的代码(server):
-
import socket, select
-
-
s = socket.socket()
-
host = socket.gethostname()
-
port = 1234
-
s.bind((host, port))
-
fdmap = {s.fileno():s}
-
-
s.listen(5)
-
p = select.poll()
-
p.register(s)
-
while True:
-
events = p.poll()
-
print 'this is out of accept()----------'
-
for fd, event in events:
-
fdc = fdmap[fd]
-
if fdc is s:
-
print 'this is the accept()'
-
c, addr = s.accept()
-
print 'Got connection from', addr
-
p.register(c)
-
fdmap[c.fileno()] = c
-
elif event & select.POLLIN:
-
data = fdmap[fd].recv(1024)
-
if not data:
-
print fdmap[fd].getpeername(), 'disconnected'
-
p.unregister(fd)
-
del fdmap[fd]
-
else:
-
print data
这个输出才叫正常,哎呦,不想在纠结上一个错误的那个啥了,但是感觉用了poll以后,socket设置阻塞和非阻塞是没什么区别的。而且确实不会卡在events = p.poll()这一句,如果没有事件发生,events会是空?反正进不去15行的for循环。然后需要注意的,events中的fd是socket.fileno()类型的,所以要判断是不是最开始被监听的socket,s,要通过一个字典fdmap,用fdmap是一个fd-->socket的映射,通过fdmap[fd]来获取对应的socket,在判断是不是s。嗯,这里不用is,用==也可以,但是据说is和==是有区别的:
Python 中 == 是判断值是否相等,is 是判断同一性,换句话说,x is y 相当于 id(x) == id(y)
每个对象都有一个独一无二的id吧。。但是“
解释器在对值很小的int和很短的字符串的时候做了一点小优化,只分配了一个对象,让它们id一样了”|
这里有一篇文章,可以参考一下:
http://my.oschina.net/cprime/blog/501
好的,话题拉回来,poll这里还是单进程来处理事件的,如果一个事件占用时间很长的话,那其他的事件只能等了,比如在30行前面加上time.sleep(5),这样其他不管是连接请求,还是消息请求,全得等5s。嗯,就是这样!
阅读(2535) | 评论(0) | 转发(0) |