Данные повреждены при чтении из потока байтов - PullRequest
0 голосов
/ 04 февраля 2019

Для сетевого проекта я использую UDP Multicast для построения оверлейной сети с собственной реализацией IP.

Сначала я использую следующее для анализа и сборки заголовка, а затем добавляю полезную нагрузку:

def __init__(buffer_size_bytes):
    self.__buffer = bytearray(buffer_size_bytes)

def read_sock(self, listening_socket):
    n_bytes, addr = listening_socket.recvfrom_into(self.__buffer, Packet.HEADER_SIZE)
    packet = Packet.parse_header(self.__buffer)

    if packet.payload_length is not 0:
        packet.payload = parse_payload(packet.payload_length, listening_socket)

    self.__router.add_to_route_queue(packet, listening_socket.locator)

def parse_payload(to_read, socket):
    payload = bytearray(to_read)
    view = memoryview(payload)
    while to_read:
        n_bytes, addr = socket.recvfrom_into(view, to_read)
        view = view[n_bytes:]
        to_read -= n_bytes

    return payload

Кажется, что заголовок анализируется правильно, но полезная нагрузка каждый раз повреждается.Я не могу понять, что я делаю неправильно, когда анализирую полезную нагрузку, и могу подтвердить, что отправляю байтовый массив с другой стороны.

Например, когда я отправляю пакет с полезной нагрузкой "Hello World ", закодированный в utf-8, я получаю следующее:

b'`\x00\x00\x00\x00\x0b\x00\x1f\x00\x00\x00'

Метод Packet.parse_header:

def parse_header(cls, packet_bytes):
    values = struct.unpack(cls.ILNPv6_HEADER_FORMAT, packet_bytes[:cls.HEADER_SIZE])

    flow_label = values[0] & 1048575
    traffic_class = (values[0] >> 20 & 255)
    version = values[0] >> 28
    payload_length = values[1]
    next_header = values[2]
    hop_limit = values[3]
    src = (values[4], values[5])
    dest = (values[6], values[7])

    return Packet(src, dest, next_header, hop_limit, version, traffic_class, flow_label, payload_length)

Для справки весь отправленный пакет выглядит так:

b'`\x00\x00\x00\x00\x0b\x00\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01Hello World'

При получении первого пакета socket.recvfrom_into блокируется при чтении полезной нагрузки и не возвращается, пока я не отправлю другое сообщение.Затем кажется, что он отбрасывает полезную нагрузку предыдущего сообщения и использует второй пакет, полученный в качестве полезной нагрузки ...

1 Ответ

0 голосов
/ 04 февраля 2019

Нашел мое объяснение здесь .

Итак, главное, что я использую UDP.А UDP-сокеты отбрасывают все, что не помещается в буфер, который вы ему даете.

TCP-сокеты, однако, ведут себя скорее как ожидаемый поток байтов.

Fun!

...