Chinaunix首页 | 论坛 | 博客
  • 博客访问: 126209
  • 博文数量: 35
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 295
  • 用 户 组: 普通用户
  • 注册时间: 2013-10-31 21:01
个人简介

明天的事情后天会知道。心怀梦想,脚踏实地!

文章分类

全部博文(35)

分类: Python/Ruby

2014-11-07 16:42:28

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

点击(此处)折叠或打开

  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。嗯,就是这样!


阅读(2487) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~