【问题标题】:Sending numpy arrays over socket between Python versions, ascii error在 Python 版本之间通过套接字发送 numpy 数组,ascii 错误
【发布时间】:2017-08-29 14:54:37
【问题描述】:

我需要在同时运行的 Python2 和 Python3 程序之间发送 numpy 数组。在做了一些研究之后,我决定通过套接字连接发送泡菜。

我能够建立连接并来回发送字符串,但尝试发送 numpy 数组会导致 ascii 错误。这是我的客户端/服务器正在做的事情:

### Imports on both client and server ###
import socket as sc
import numpy
try:
    import cPickle as pickle
except ImportError:
    import pickle
pickle.HIGHEST_PROTOCOL = 2

### Python2 client ###
data= numpy.ones((1, 60))
sock.connect(SERVER_ADDR)

try:
    serialized_data = pickle.dumps(data, protocol=2)
except pickle.PicklingError as e:
    raise e

try:
    sock.send(serialized_data )
except sc.error as e:
    logging.error('Connection ended')

### Python3 server ###
"""
Given a client socket, and until the client has closed the session:
- receive input from client
- unpickle and print it
"""

while client != '':
    try:
        data = client.recv(4096)
    except sc.error as e:
        if e.errno != errno.ECONNRESET:
            print('Connection ended')
    else:
        try:
            unserialized_input = pickle.loads(input) ##### ERROR HERE #####
        except pickle.UnpicklingError as e:
            raise e
        else:
            print(unserialized_input)

### Error on server ###
UnicodeDecodeError: 'ascii' codec can't decode byte 0xf0 in position 6: ordinal not in range(128)

我尝试搜索相关问题,但除了建议的解决方案here 之外找不到任何相关内容,因为我需要使用 Python2,所以这对我不起作用。我不确定如何继续。有什么想法吗?

【问题讨论】:

标签: python sockets pickle


【解决方案1】:

我重现了您在 Python 3 上运行服务器和在 Python 2 上运行客户端的错误。以下代码是一个示例,可以在任何 Python 组合上运行服务器和客户端。 Python 3 上的pickle.loads 默认使用ascii 解码字符串。要将它们保留为发送的原始字节,请添加 encoding='bytes' 作为参数。

我的协议是“从客户端读取所有内容,直到客户端关闭连接,然后对其进行反序列化”。如果要保持连接打开并发送多个序列化 blob,则必须定义一个协议来指示序列化 blob 的长度。

客户:

import socket
import numpy

try:
    import cPickle as pickle
except ImportError:
    import pickle

sock = socket.socket()
data= numpy.ones((1, 60))
sock.connect(('localhost',8000))
serialized_data = pickle.dumps(data, protocol=2)
sock.sendall(serialized_data)
sock.close()
sock = socket.socket()
data= numpy.zeros((1, 60))
sock.connect(('localhost',8000))
serialized_data = pickle.dumps(data, protocol=2)
sock.sendall(serialized_data)
sock.close()

服务器:

from __future__ import print_function
import sys
import socket
import numpy

try:
    import cPickle as pickle
except ImportError:
    import pickle

s = socket.socket()
s.bind((b'',8000))
s.listen(1)
while True:
    c,a = s.accept()
    data = b''
    while True:
        block = c.recv(4096)
        if not block: break
        data += block
    c.close()
    if sys.version_info.major < 3:
        unserialized_input = pickle.loads(data)
    else:
        unserialized_input = pickle.loads(data,encoding='bytes')
    print(unserialized_input)

输出:

[[ 1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.
   1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.
   1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.  1.
   1.  1.  1.  1.  1.  1.]]
[[ 0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.
   0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.
   0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.  0.
   0.  0.  0.  0.  0.  0.]]

【讨论】:

    猜你喜欢
    • 2014-12-10
    • 1970-01-01
    • 1970-01-01
    • 2014-03-31
    • 1970-01-01
    • 2014-08-16
    • 1970-01-01
    • 2023-03-22
    • 2014-09-01
    相关资源
    最近更新 更多