通过套接字发送和接收数组

9

是否可以使用Python通过UDP套接字发送数组?我正在使用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

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

在处理IT技术相关内容时,我个人会使用tostringfromstring方法,因为它们内置的序列化方法速度更快,而pickle可能不支持NaN、Inf和其他未定义的值。


1
“pickle”在传输numpy数组方面非常糟糕,绝对不可取。pickle是平台相关的,在传输numpy数组方面极其低效,并且numpy模块提供了非常好的序列化支持,例如“tostring”和“fromstring”,但这些方法都是复制方法。我实施的最佳解决方案是使用Cython。 - lukecampbell

4

您正在尝试通过套接字发送Python对象,无法正常工作是很正常的,因为您无法在套接字中发送对象,对象不是数据,它们只是某种编程语言中某些数据的表示。您需要将对象“翻译”成数据,并在另一个套接字的一侧从数据重新创建对象。一种方法是使用pickle模块。

在客户端上,“pickle”对象:

data = pickle.dumps(my_array)

在服务器端,您需要“反序列化”接收到的数据:

my_array = pickle.loads(received_data)

3
你可以尝试使用 pickle 序列化数组。Pickle 是一个 Python 库,用于编码和解码 Python 对象。它能够做更多的事情,但是绝对足够满足你的需求:
在发送端,你需要将对象序列化为字符串:pickle
pickled_string = pickle.dumps(a)

在接收方,你需要使用unpickle函数对对象进行反序列化:
a = pickle.loads(received_string)
# a is now your sent array

1

这个问题被问了一段时间,但我认为分享 jsonsocket 是值得的。它使得通过 sockets 发送字符串、列表和字典变得非常容易。它能够高效地处理大量数据,并且您无需进行任何手动序列化 / 反序列化操作。在底层,它将数据作为 JSON 字符串在客户端上进行序列化,然后在服务器上进行反序列化。


1
这是一个非常好的库。它为我节省了大量时间和精力! - Anton

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接