Receive a raw BSON message or raise socket.error.

def receive_message(
        sock, operation, request_id, max_message_size=MAX_MESSAGE_SIZE):
    """Receive a raw BSON message or raise socket.error."""
    header = _receive_data_on_socket(sock, 16)
    length = _UNPACK_INT(header[:4])[0]

    actual_op = _UNPACK_INT(header[12:])[0]
    if operation != actual_op:
        raise ProtocolError("Got opcode %r but expected "
                            "%r" % (actual_op, operation))
    # No request_id for exhaust cursor "getMore".
    if request_id is not None:
        response_id = _UNPACK_INT(header[8:12])[0]
        if request_id != response_id:
            raise ProtocolError("Got response id %r but expected "
                                "%r" % (response_id, request_id))
    if length <= 16:
        raise ProtocolError("Message length (%r) not longer than standard "
                            "message header size (16)" % (length,))
    if length > max_message_size:
        raise ProtocolError("Message length (%r) is larger than server max "
                            "message size (%r)" % (length, max_message_size))

    return _receive_data_on_socket(sock, length - 16)