3. Asynchronous Network Programming (asyncoro)


asyncoro has been renamed pycos to better reflect its functionality and to avoid confusion with asyncore module.

asyncoro provides AsyncSocket that converts synchronous (regular) sockets created with socket.socket to asynchronous sockets to be used in coroutines. I/O methods, such as connect, send, receive etc. of asynchronous sockets should be used with yield. These methods simply schedule I/O operation and due to yield give control to AsynCoro scheduler scheduler so that other coroutines can be executed while the I/O operation is pending. When the I/O operation is complete, the coroutine that executed the I/O operation becomes eligible for execution. The API described below can be used for asynchronous network programming.

3.1. Examples

See Asynchronous Network Programming in tutorial for an example. There are many illustrative use cases in ‘examples’ directory under where asyncoro module is installed.

Following is a brief description of the examples included relevant to this section:

3.2. Asynchronous Socket

The API with asynchronous socket is virtually same as that with synchronous sockets, except for using yield with methods that would block, e.g., send, receive, accept.

class asyncoro.AsyncSocket(sock, blocking=False, keyfile=key, certfile=cert, ssl_version=version)

Converts a synchronous (regular) socket sock (created with socket.socket) to an asynchronous (non-blocking) socket.

blocking is either True or False. If it is False (default), the socket will be setup for asynchronous operations and if it is True, it will be setup for synchronous operations (see below).

keyfile, certfile and ssl_version are as per wrap_socket() method in ssl module.

Socket methods accept(), connect(), send(), recv(), sendall(), sendto() and recvfrom() for asynchronous sockets must be used with yield. The value of such yield statement is the result of the socket I/O operation (for example, for yield recv(1024), it would be the buffer received by the socket). These methods should only be used on asynchronous sockets (i.e., sockets converted with blocking=Falsee) in coroutines and on synchronous sockets (i.e,. sockets converted with blocking=True) in main thread or in other thread functions.

asyncoro’s socket implementation adds recvall(), send_msg(), recv_msg() methods. These methods must be used with yield when using with asynchronous sockets.:

  • buf = yield recvall(n) receives exactly given number of bytes n (counterpart to sendall()), unlike recv() which receives up to n bytes,
  • yield send_msg(buf) sends the given buffer similar to sendall() with the length of the buffer prefixed, so that receiving side knows exactly how many bytes to receive,
  • buf = yield recv_msg() receives full buffer sent by send_msg().

The socket returned from accept() method of an asynchronous socket is also an asynchronous socket, so there is no need to convert it to asynchronous version.

Sockets converted with blocking=True are to be use in threads, and not in coroutines. Such sockets can use all the methods provided by socket.socket (without yield, required only for asynchronous sockets), and use additional methods provided by AsyncSocket recvall, send_msg and recv_msg.