The sort service example should look familiar by now, as it has a similar boilerplate to other AsyncIO programs. However, there are a few differences. We called start_server instead of create_server. This method hooks into AsyncIO's streams instead of using the underlying transport/protocol code. It allows us to pass in a normal coroutine, which receives reader and writer parameters. These both represent streams of bytes that can be read from and written, like files or sockets. Second, because this is a TCP server instead of UDP, there is some socket cleanup required when the program finishes. This cleanup is a blocking call, so we have to run the wait_closed coroutine on the event loop.
Streams are fairly simple to understand. Reading is a potentially blocking call so we have to call it with await. Writing doesn't block; it just puts the data in a queue, which AsyncIO sends out in the background.
Our code inside the sort_request method makes two read requests. First, it reads 8 bytes from the wire and converts them to an integer using big endian notation. This integer represents the number of bytes of data the client intends to send. So, in the next call, to readexactly, it reads that many bytes. The difference between read and readexactly is that the former will read up to the requested number of bytes, while the latter will buffer reads until it receives all of them, or until the connection closes.