liveBook · Manning

Socket.recv

As explained in Python Concurrency with asyncio

socket.recv is a socket method that reads up to a specified number of bytes from the socket.

socket.recv reads up to a specified number of bytes from a socket. Because socket input may arrive in pieces, applications usually call recv repeatedly and buffer the results until a message boundary appears. section 3.2.1

Use recv with these practical rules:

  • Pass an integer byte limit, such as 2 for a deliberately small demonstration buffer or 1024 for a more practical application buffer. section 3.2.1
  • Append each returned byte string to a buffer and stop when the protocol delimiter, such as carriage return plus line feed, is present. section 3.2.1
  • Remember that blocking sockets make recv wait for data, potentially preventing other clients from being processed. section 3.2.2

Read a Telnet line in pieces

A server can repeatedly call connection.recv(2), append each result to buffer, and stop when buffer ends with b'\r\n'. Sending testing123 through Telnet produces chunks such as b'te', b'st', and b'\r\n', which combine into b'testing123\r\n'.

Listing 3.7 Using selectors to build a non-blocking server
import selectors
import socket
from selectors import SelectorKey
from typing import List, Tuple
 
selector = selectors.DefaultSelector()
 
server_socket = socket.socket()
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
 
server_address = ('127.0.0.1', 8000)
server_socket.setblocking(False)
server_socket.bind(server_address)
server_socket.listen()
 
selector.register(server_socket, selectors.EVENT_READ)
 
while True:
    events: List[Tuple[SelectorKey, int]] = selector.select(timeout=1)  #1
 
    if len(events) == 0:                                                #2
        print('No events, waiting a bit more!')
 
    for event, _ in events:
        event_socket = event.fileobj                                    #3
 
        if event_socket == server_socket:                               #4
            connection, address = server_socket.accept()
            connection.setblocking(False)
            print(f"I got a connection from {address}")
            selector.register(connection, selectors.EVENT_READ)         #5
        else:
            data = event_socket.recv(1024)                              #6
            print(f"I got some data: {data}")
            event_socket.send(data)

Inspect a selectors-based echo server that calls socket.recv only after the operating system reports a read event, avoiding blocking while serving multiple clients. section 3.4

How Python Concurrency with asyncio covers it

How deep it goes
Explains byte limits, buffering, delimiters, connection closure, blocking, and selector-driven reads without descending into recv internals.
Examples
Demonstrates recv through a Telnet client, a line-buffering echo server, and a selectors-based multi-client server.
What it assumes
Assumes basic Python socket creation and client-server connections while teaching byte buffering and read readiness progressively.
What you can do after
Apply recv to assemble delimited messages and diagnose blocking behavior in socket servers.
How it connects
Connects recv with sockets, buffering, blocking I/O, non-blocking sockets, selectors, event loops, and asyncio.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Python Concurrency with asyncio. The section links point to the parts of the book it draws on.