Skip to content

Instantly share code, notes, and snippets.

@CesarNog
Forked from dabeaz/aecho.py
Created November 11, 2015 13:30
Show Gist options
  • Select an option

  • Save CesarNog/965a6c85f979aa9ed918 to your computer and use it in GitHub Desktop.

Select an option

Save CesarNog/965a6c85f979aa9ed918 to your computer and use it in GitHub Desktop.

Revisions

  1. @dabeaz dabeaz created this gist Nov 10, 2015.
    29 changes: 29 additions & 0 deletions aecho.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,29 @@
    # aecho.py

    from socket import *
    import asyncio

    loop = asyncio.get_event_loop()

    async def echo_server(address):
    sock = socket(AF_INET, SOCK_STREAM)
    sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
    sock.bind(address)
    sock.listen(5)
    sock.setblocking(False)
    while True:
    client, addr = await loop.sock_accept(sock)
    print('Connection from', addr)
    loop.create_task(echo_handler(client))

    async def echo_handler(client):
    with client:
    while True:
    data = await loop.sock_recv(client, 10000)
    if not data:
    break
    await loop.sock_sendall(client, b'Got:'+data)
    print('Connection closed')

    loop.create_task(echo_server(('',25000)))
    loop.run_forever()
    29 changes: 29 additions & 0 deletions pecho.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,29 @@
    # pecho.py

    from socket import *
    import play

    loop = play.Loop()

    async def echo_server(address):
    sock = socket(AF_INET, SOCK_STREAM)
    sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
    sock.bind(address)
    sock.listen(5)
    sock.setblocking(False)
    while True:
    client, addr = await loop.sock_accept(sock)
    print('Connection from', addr)
    loop.create_task(echo_handler(client))

    async def echo_handler(client):
    with client:
    while True:
    data = await loop.sock_recv(client, 10000)
    if not data:
    break
    await loop.sock_sendall(client, b'Got:'+data)
    print('Connection closed')

    loop.create_task(echo_server(('',25000)))
    loop.run_forever()
    59 changes: 59 additions & 0 deletions play.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,59 @@
    # play.py

    from types import coroutine
    from collections import deque
    from selectors import DefaultSelector, EVENT_READ, EVENT_WRITE

    @coroutine
    def read_wait(sock):
    yield 'read_wait', sock

    @coroutine
    def write_wait(sock):
    yield 'write_wait', sock

    class Loop:
    def __init__(self):
    self.ready = deque()
    self.selector = DefaultSelector()

    async def sock_recv(self, sock, maxbytes):
    await read_wait(sock)
    return sock.recv(maxbytes)

    async def sock_accept(self, sock):
    await read_wait(sock)
    return sock.accept()

    async def sock_sendall(self, sock, data):
    while data:
    try:
    nsent = sock.send(data)
    data = data[nsent:]
    except BlockingIOError:
    await write_wait(sock)

    def create_task(self, coro):
    self.ready.append(coro)

    def run_forever(self):
    while True:
    while not self.ready:
    events = self.selector.select()
    for key, _ in events:
    self.ready.append(key.data)
    self.selector.unregister(key.fileobj)

    while self.ready:
    self.current_task = self.ready.popleft()
    try:
    op, *args = self.current_task.send(None) # Run to the yield
    getattr(self, op)(*args) # Sneaky method call
    except StopIteration:
    pass

    def read_wait(self, sock):
    self.selector.register(sock, EVENT_READ, self.current_task)

    def write_wait(self, sock):
    self.selector.register(sock, EVENT_WRITE, self.current_task)