Отправка двоичных данных через сокеты в 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 строку.