python中socket编程poll的使用

废话不说,看代码和结果
      这个是服务器端的 

点击(此处)折叠或打开

  1. #  server_p.py
  2. import socket, select

  3. = socket.socket()
  4. host = socket.gethostname()
  5. port = 1234
  6. s.bind((host, port))
  7. s.setblocking(False)
  8. fdmap = {s.fileno():s}

  9. s.listen(5)
  10. = select.poll()
  11. p.register(s)
  12. while True:
  13.         events = p.poll()
  14.         print 'this is out of evennt.............'
  15.         for fd, event in events:
  16.                 if fd in fdmap:
  17.                         print 'this is the accept()'
  18.                         try:
  19.                                 c, addr = s.accept()
  20.                                 print 'Got connection from', addr
  21.                                 print 'after accept'
  22.                                 p.register(c)
  23.                                 fdmap[c.fileno()] = c
  24.                                 try:
  25.                                         data = c.recv(1024)
  26.                                         print data
  27.                                 except Exception, e:
  28.                                         print 'this is the except:', e
  29.                         except Exception, e:
  30.                                 print 'this is the exception:', e


  31.                 elif event & select.POLLIN:
  32.                         print 'this is the event'
  33.                         data = fdmap[fd].recv(1024)
  34.                         if not data:
  35.                                 print fdmap[fd].getpeername(), 'disconnected'
  36.                                 p.unregister(fd)
  37.                                 del fdmap[fd]
  38.                         else:
  39.                                 print data
    客户端,客户端很简单,也可以直接用telnet实现同样的功能:

点击(此处)折叠或打开

  1. # client.py
  2. import socket, time
  3. s = socket.socket()
  4. host = socket.gethostname()
  5. port = 1234
  6. s.connect((host,port))
  7. s.send('this is the client')
  8. time.sleep(5)
  9. s.send('hahah----------------------------')
  10. s.close()

诡异的结果啊,

结果就是,服务器(客户端没啥好说的,不作说明,都指服务器),p.poll()不会阻塞啊,而且不管有没有连接都会进入里面的循环中,这意味着events竟然一直有东西,我去啊啊,这是怎么回事,好吧,先澄清一点,就是,这里的server是有问题的,elif分支完全不会进去,前面if fd in fdmap感觉一点用逗没有,不如换为if fdmap[fd] is s,即判断该事件的socket是不是正在被监听的socket,从而判断是有连接请求过来,还是其他已经建立好的连接有消息发过来。这里太诡异了
来份正常的代码(server):

点击(此处)折叠或打开

  1. import socket, select

  2. s = socket.socket()
  3. host = socket.gethostname()
  4. port = 1234
  5. s.bind((host, port))
  6. fdmap = {s.fileno():s}

  7. s.listen(5)
  8. p = select.poll()
  9. p.register(s)
  10. while True:
  11.         events = p.poll()
  12.         print 'this is out of accept()----------'
  13.         for fd, event in events:
  14.                 fdc = fdmap[fd]
  15.                 if fdc is s:
  16.                         print 'this is the accept()'
  17.                         c, addr = s.accept()
  18.                         print 'Got connection from', addr
  19.                         p.register(c)
  20.                         fdmap[c.fileno()] = c
  21.                 elif event & select.POLLIN:
  22.                         data = fdmap[fd].recv(1024)
  23.                         if not data:
  24.                                 print fdmap[fd].getpeername(), 'disconnected'
  25.                                 p.unregister(fd)
  26.                                 del fdmap[fd]
  27.                         else:
  28.                                 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。嗯,就是这样!


<script>window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"2","bdMiniList":false,"bdPic":"","bdStyle":"0","bdSize":"16"},"share":{}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];</script>
阅读(4) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~
评论热议
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值