Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1782201
  • 博文数量: 297
  • 博客积分: 285
  • 博客等级: 二等列兵
  • 技术积分: 3006
  • 用 户 组: 普通用户
  • 注册时间: 2010-03-06 22:04
个人简介

Linuxer, ex IBMer. GNU https://hmchzb19.github.io/

文章分类

全部博文(297)

文章存档

2020年(11)

2019年(15)

2018年(43)

2017年(79)

2016年(79)

2015年(58)

2014年(1)

2013年(8)

2012年(3)

分类: Python/Ruby

2019-07-04 22:08:58

这个书刚开始看,翻了第一章感觉是在教你如何写类似twisted这样的框架,感觉不错。
异步asyncio 和twisted 对我来说是很复杂的,总感觉是对应c里面的select/epoll
就是多路复用。

但是有些地方略晕,
python3的non-block 会触发的exception 改成了BlockingIOError。
python2里面是socket.error
但我试了下在try exception里面这两种exception 都可以。
except BlockingIOError as e:
或者
except socket.error as e:

另外,该书在github上的代码不全。
我自己敲了第一章20页的完整代码,
该代码会触发MemoryError.

点击(此处)折叠或打开

  1. import select

  2. class Reactor:
  3.     def __init__(self):

  4.         self._readers = {}
  5.         self._writers = {}
  6.     
  7.     def addReader(self, readable, handler):
  8.         self._readers[readable]= handler
  9.     
  10.     def addWriter(self, writable, handler):
  11.         self._writers[writable]=handler
  12.     
  13.     def removeReader(self, readable):
  14.         self._readers.pop(readable, None)
  15.     
  16.     
  17.     def removeWriter(self, writable):
  18.         self._writers.pop(writable, None)
  19.     
  20.     def run(self):
  21.         while self._readers or self._writers:
  22.             r, w, _ = select.select(list(self._readers), list(self._writers),[])
  23.             for readable in r:
  24.                 self._readers[readable](self, readable)
  25.             
  26.             for writable in w:
  27.                 if writable in self._writers:
  28.                     self._writers[writable](self, writable)

  29. import errno
  30. import socket

  31. class BuffersWrites:
  32.     def __init__(self, dataToWrite, onCompletion):
  33.         self._buffer = dataToWrite
  34.         self._onCompletion = onCompletion
  35.     
  36.     def bufferingWrite(self, reactor, sock):
  37.         if self._buffer:
  38.             try:
  39.                 written = sock.send(self._buffer)
  40.             except socket.error as e:
  41.                 if e.errno != errno.EAGAIN:
  42.                     raise
  43.                 return
  44.             else:
  45.                 print("Wrote", written, ' bytes')
  46.                 self._buffer = self._buffer[written:]
  47.         if not self._buffer:
  48.             reactor.removeWriter(sock)
  49.             self._onCompletion(reactor, sock)


  50. def accept(reactor, listener):
  51.     server, _ = listener.accept()
  52.     #server.setblocking(False)
  53.     reactor.addReader(server, read)

  54. def read(reactor, sock):
  55.     data = sock.recv(1024)
  56.     if data:
  57.         print("Server received", len(data), ' bytes')
  58.     else:
  59.         sock.close()
  60.         print("Server closed")
  61.         reactor.removeReader(sock)
  62.         

  63. DATA=[b'*', b'*']
  64. def write(reactor, sock):
  65.     writer = BuffersWrites(b''.join(DATA), onCompletion=write)
  66.     reactor.addWriter(sock, writer.bufferingWrite)
  67.     print('Client buffering', len(DATA), ' bytes to write.')
  68.     DATA.extend(DATA)

  69. sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  70. sock.bind(('127.0.0.1', 0))
  71. sock.listen(1)
  72. client= socket.create_connection(sock.getsockname())
  73. client.setblocking(False)

  74. loop = Reactor()
  75. loop.addWriter(client, write)
  76. loop.addReader(sock, accept)
  77. loop.run()


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