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