Python: как передавать массивы переменной длины по сетевому соединению

Мне нужно передать массив разной длины, в котором каждый элемент представляет собой кортеж из двух целых чисел. Например:

path = [(1,1),(1,2)]
path = [(1,1),(1,2),(2,2)]

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

msg = 1&1~1&2~
sendMsg = pack("s",msg) or sendMsg = pack("s",str(msg))

на принимающей стороне:

path = unpack("s",msg)

но это просто печатает 1 в этом случае. Я также пытался отправить 4 целых числа, которые отправляются и получаются нормально, если я не включаю дополнительную строку, представляющую путь.

sendMsg = pack("hhhh",p.direction[0],p.direction[1],p.id,p.health)

на принимающей стороне:

x,y,id,health = unpack("hhhh",msg)

Первый был для иллюстрации, поскольку я пытался отправить формат «hhhhs», но в любом случае путь не проходит должным образом.

Спасибо за помощь. Я также рассмотрю отправку 2D-массива целых чисел, но я не могу понять, как отправлять эти более «сложные» структуры по сети.

Спасибо за помощь.


person Devin    schedule 27.03.2010    source источник


Ответы (5)


Хотя вы можете использовать упаковывать и распаковывать, я бы рекомендовал использовать что-то вроде YAML или JSON для передачи ваших данных.

  • Упаковка и распаковка могут привести к трудным для отладки ошибкам и несовместимости, если вы измените свой интерфейс и разные версии пытаются взаимодействовать друг с другом.
  • Pickle может создавать проблемы с безопасностью, а формат pickle может меняться в разных версиях Python.

JSON включен в стандартный дистрибутив Python с версии 2.6. Для YAML есть PyYAML.

person Mark Byers    schedule 27.03.2010

Вам нужен какой-то протокол сериализации. twisted.spread предоставляет один такой (см. спецификацию Banana или документация Perspective Broker). Более подробными примерами могут быть JSON или протокольные буферы.

См. также Сравнение форматов сериализации данных.

person keturn    schedule 27.03.2010

Если вы включите длину сообщения как часть сообщения, вы будете знать, сколько данных нужно прочитать. Таким образом, вся строка должна быть прочитана по сети.

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

person Justin Ethier    schedule 27.03.2010

Взгляните на xdrlib, это может помочь. Это часть стандартной библиотеки, и:

Модуль xdrlib поддерживает стандарт представления внешних данных, как описано в RFC 1014. , написанный Sun Microsystems, Inc. в июне 1987 г. Он поддерживает большинство типов данных, описанных в RFC.

person tzot    schedule 27.03.2010

Упаковывать и распаковывать обязательно? Если нет, вы можете использовать JSON и YAML.

Не используйте pickle, так как это небезопасно.

person systempuntoout    schedule 27.03.2010
comment
Как упоминает Марк Байерс, pickle небезопасен, если вы используете его в сети, где вы не хотите, чтобы тот, кто отправляет данные, мог запускать произвольный код на машине получателя. nadiana.com/python-pickle-insecure - person keturn; 28.03.2010
comment
Я не знал об этих возможных подвигах. - person systempuntoout; 28.03.2010