Отправка двоичных данных через сокеты в Python

Я ищу сценарий некоторых основных запросов над протокол SPDY. Протокол определяет кадры, которые вы отправляете, как состоящие из двоичных данных очень определенной длины и порядка байтов.

Я только когда-либо писал небольшие программы, которые отправляют строки через сокеты (HTTP). Как, например, реализовать заголовок фрейма управления SPDY? Я попытался использовать библиотеку bitstring и numpy для управления размером всех различных разделов фрейма управления например, header, но ничего не работает. Текущая библиотека SPDY для python использует типы данных cython и C, и я нашел ее очень непредсказуемой. Мне было интересно, как я могу создавать простые запросы с помощью pure python или очень просто, как я могу создавать что-то точно так, как определяет протокол и отправлять его через сокет?

2 ответов


вообще bytearray класс будет вашим другом (если я правильно понимаю ваш вопрос). Вы можете отправить его через сокет:

my_bytes = bytearray()
my_bytes.append(123)
my_bytes.append(125)

// my_bytes is b'{}' now

s.send(my_bytes)

следуйте спецификации протокола и создавайте байт за байтом. Это также работает, когда вы получаете данные:

data = s.recv(2048)
my_bytes = bytearray(data)

Я мало знаю о протоколе SPDY, но, например, бит управления является первым немного (не байт) в сообщении. Вы можете получить его из my_bytes через двоичный файл и для пример:

control_frame = my_bytes[0] & 128

это так 128 is 10000000 в двоичном и, следовательно, двоичном и даст вам только первый бит (помните, что каждый байт имеет 8 бит, поэтому у нас есть 7 нулей).

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


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

создать пакет:

fmt = 'B I 4b'
your_binary_data = pack(fmt, header_data)
sock.sendall(your_binary_data)

здесь fmt указывает формат заголовка ("B I 4b" - это просто a, явно не работает для вашего заголовка SPDY, например). К сожалению, вам придется иметь дело с полями заголовка без байтов, вероятно, путем разбора больших кусков, а затем деления их в соответствии с вашим форматом.

в сторону, чтобы разобрать заголовок:

unpacker = struct.Struct('B I 4b')
unpacked_data = unpacker.unpack(s.recv(unpacker.size))

unpacked_data будет содержать кортеж с проанализированными данными.

на модуля struct выполняет преобразования между значениями Python и структурами C, представленными в виде строк Python. У меня нет гарантий эффективности этого подхода, но он помог мне проанализировать различные протоколы, просто настроив fmt строку.