Отправка и получение массивов через сокеты - PullRequest
9 голосов
/ 18 августа 2011

Можно ли отправить массив через UDP-сокеты с помощью Python?Я использую Python 2.5 и пытаюсь отправить простой массив, но он не работает.Он может успешно отправить массив, но когда я пытаюсь напечатать его с элементом массива, программа вылетает.Я не уверен, что ошибка, поскольку я принимаю меры предосторожности при преобразовании данных в массив, но это не работает.Надеюсь, я объяснил проблему как можно яснее.Буду признателен за помощь!

# Client program

from socket import *
import numpy
from array import*

# Set the socket parameters
host = "localhost"
port = 21567
buf = 4096
addr = (host,port)

# Create socket
UDPSock = socket(AF_INET,SOCK_DGRAM)

def_msg = "===Enter message to send to server===";
print "\n",def_msg
a = array('i',[1,3,2])
# Send messages
while (1):
    data = raw_input('yes or now')
    if data!= "yes":
        break
    else:
        if(UDPSock.sendto(a,addr)):
            print "Sending message"

# Close socket
UDPSock.close()



# Server program

from socket import *

# Set the socket parameters
host = "localhost"
port = 21567
buf = 4096
addr = (host,port)

# Create socket and bind to address
UDPSock = socket(AF_INET,SOCK_DGRAM)
UDPSock.bind(addr)

# Receive messages
while 1:
    data,addr = UDPSock.recvfrom(buf)
    L = eval(data)
    if not data:
        print "Client has exited!"
        break
    else:
        print "\nReceived message '", L[1],"'"

# Close socket
UDPSock.close()

Ответы [ 6 ]

14 голосов
/ 18 августа 2011

eval делает что-то совершенно иное, чем вы думаете.

Чтобы отправить данные по сети, вам нужно сериализовать их в массив байтов, затем десериализовать их обратно. В Python сериализация большинства объектов может быть выполнена с помощью модуля pickle:

if (UDPSock.sendto( pickle.dumps(a), addr)):

Десериализация:

data,addr = UDPSock.recvfrom(buf)
L = pickle.loads(data)
print repr(L) # prints array('i', [1, 3, 2])
6 голосов
/ 18 августа 2011

Я бы лично использовал tostring и fromstring, поскольку встроенные методы сериализации во много раз быстрее , а pickle может не поддерживать NaN,Inf и другие неопределенные значения.

4 голосов
/ 18 августа 2011

Вы пытаетесь отправить объект python через сокет, это нормально, что он не работает, вы не можете отправлять объекты в сокет, объекты не являются данными, они представляют собой некоторые данные в данный язык программирования. Вам нужно «перевести» ваш объект в данные и воссоздать объект из данных на стороне другого сокета. Один из способов сделать это - использовать модуль pickle.

На стороне клиента вы "мариноваете" объект:

data = pickle.dumps(my_array)

А на стороне сервера вы «распаковываете» полученные данные:

my_array = pickle.loads(received_data)
3 голосов
/ 18 августа 2011

Вы можете попробовать pickle массив. Pickle - это библиотека Python для кодирования и декодирования объектов Python. Он может сделать гораздо больше, но этого вполне достаточно для выполнения вашей задачи:

на стороне отправителя вы pickle объект в строку:

pickled_string = pickle.dumps(a)

на стороне получателя вы unpickle объект:

a = pickle.loads(received_string)
# a is now your sent array
1 голос
/ 01 мая 2014

Прошло много времени с тех пор, как этот вопрос был задан, но я подумал, что стоит поделиться библиотекой jsonsocket . Это позволяет легко отправлять строки, списки и словари через сокеты. Он может эффективно обрабатывать большие объемы данных. И вам не нужно делать какую-либо ручную сериализацию / десериализацию. Изнутри он сериализует данные в виде строк JSON на клиенте и десериализует их на сервере.

0 голосов
/ 26 июня 2015

Если вам конкретно не нужен UDP, попробуйте zmqObjectExchanger (https://github.com/ZdenekM/zmq_object_exchanger).. Он переносит pickle и zmq для передачи объектов python по TCP.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...