def _recvall(sock, size):
    """
    Read exactly the specified amount of data from a socket.  If a
    ``recv()`` call returns less than the requested amount, the
    ``recv()`` is retried until it either returns EOF or all the
    requested data has been read.

    :param sock: A socket from which bytes may be read.
    :param int size: The amount of data to read from the socket.

    :returns: The requested data.
    """

    data = b''

    while len(data) < size:
        buf = sock.recv(size - len(data))

        # Break out if we got an EOF
        if not buf:
            # Return None for an EOF
            return data or None

        data += buf

    return data