异步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.
点击(此处)折叠或打开
- import select
- class Reactor:
- def __init__(self):
- self._readers = {}
- self._writers = {}
-
- def addReader(self, readable, handler):
- self._readers[readable]= handler
-
- def addWriter(self, writable, handler):
- self._writers[writable]=handler
-
- def removeReader(self, readable):
- self._readers.pop(readable, None)
-
-
- def removeWriter(self, writable):
- self._writers.pop(writable, None)
-
- def run(self):
- while self._readers or self._writers:
- r, w, _ = select.select(list(self._readers), list(self._writers),[])
- for readable in r:
- self._readers[readable](self, readable)
-
- for writable in w:
- if writable in self._writers:
- self._writers[writable](self, writable)
- import errno
- import socket
- class BuffersWrites:
- def __init__(self, dataToWrite, onCompletion):
- self._buffer = dataToWrite
- self._onCompletion = onCompletion
-
- def bufferingWrite(self, reactor, sock):
- if self._buffer:
- try:
- written = sock.send(self._buffer)
- except socket.error as e:
- if e.errno != errno.EAGAIN:
- raise
- return
- else:
- print("Wrote", written, ' bytes')
- self._buffer = self._buffer[written:]
- if not self._buffer:
- reactor.removeWriter(sock)
- self._onCompletion(reactor, sock)
- def accept(reactor, listener):
- server, _ = listener.accept()
- #server.setblocking(False)
- reactor.addReader(server, read)
- def read(reactor, sock):
- data = sock.recv(1024)
- if data:
- print("Server received", len(data), ' bytes')
- else:
- sock.close()
- print("Server closed")
- reactor.removeReader(sock)
-
- DATA=[b'*', b'*']
- def write(reactor, sock):
- writer = BuffersWrites(b''.join(DATA), onCompletion=write)
- reactor.addWriter(sock, writer.bufferingWrite)
- print('Client buffering', len(DATA), ' bytes to write.')
- DATA.extend(DATA)
- sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- sock.bind(('127.0.0.1', 0))
- sock.listen(1)
- client= socket.create_connection(sock.getsockname())
- client.setblocking(False)
- loop = Reactor()
- loop.addWriter(client, write)
- loop.addReader(sock, accept)
- loop.run()