Отправка и прием массивов через сокеты

можно ли отправить массив через 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 ответов


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])

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


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

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

pickled_string = pickle.dumps(a)

на стороне приемника вы unpickle объект:

a = pickle.loads(received_string)
# a is now your sent array

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

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

data = pickle.dumps(my_array)

и на на стороне сервера вы" распаковываете " полученные данные:

my_array = pickle.loads(received_data)

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


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