2011-08-18 206 views
8

是否可以通过使用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() 

回答

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

This Works,Thank you! – dawnoflife

3

你可以试试pickle这个数组。 Pickle是一个Python库,用于编译和解码python对象。它能够做更多的事情,但它绝对是足以满足你的任务:发送侧

pickle对象为字符串:

pickled_string = pickle.dumps(a) 

在接收端你unpickle对象:

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

你试图通过套接字发送一个Python对象,这是正常的,这是行不通的,你不能在一个插座发送对象,对象不是数据,他们的表现一些给定的编程语言中的数据。您需要将您的对象“翻译”为数据,并从另一个套接字端的数据重新创建对象。一种方法是使用pickle模块。

在客户端,你 “泡菜” 的对象:

data = pickle.dumps(my_array) 

而在服务器端,你 “unpickle” 接收到的数据:

my_array = pickle.loads(received_data) 
+0

我只能接受1个答案,但是谢谢你的回复! – dawnoflife

6

我会亲自使用tostringfromstring因为内置的序列化方法是many times faster和咸菜may not support的NaN ,Inf和其他未定义的值。

+1

'pickle'发送numpy数组非常糟糕,绝对可怕。 Picke依赖于平台,发送numpy数组的效率非常低,numpy在模块中提供了很好的序列化支持,比如'tostring'和'fromstring',但这些都是复制方法。我已经实施的最好的解决方案是使用Cython。 – lukecampbell

1

自问这个问题已经有一段时间了,但我认为值得分享jsonsocket library。它使得通过套接字发送字符串,列表和字典变得非常简单。它可以高效地处理大量的数据。而且您不需要执行任何手动序列化/反序列化。在引擎盖下,它将数据序列化为客户端上的JSON字符串,并在服务器上对其进行反序列化。

+1

这是一个非常好的图书馆。它为我节省了很多时间和精力! – Anton