我遇到cPickle错误,不知道是什么意思,有人知道这是什么吗?

3 投票
1 回答
1396 浏览
提问于 2025-04-17 06:30

我在使用一个进程通信的RMC,下面是我的代码:

    HOST = ''     # local host
    PORT = 50000
    SERVER_ADDRESS = HOST, PORT

    # set up server socket
    s = socket.socket()
    s.bind(SERVER_ADDRESS)
    s.listen(1)

    while True:
        conn, addr = s.accept()
        connFile = conn.makefile()
        name, args, kwargs = cPickle.load(connFile)
        '''name = cPickle.load(connFile)
        args = cPickle.load(connFile)
        kwargs = cPickle.load(connFile)'''
        res = _exportedMethods[name](*args,**kwargs)
        cPickle.dump(res,connFile) ; connFile.flush()
        conn.close()

这是客户端的代码:

class RemoteFunction(object):
    def __init__(self,serverAddress,name):
        self.serverAddress = serverAddress
        self.name = name
    def __call__(self,*args,**kwargs):
        s = socket.socket()
        s.connect(self.serverAddress)
        f = s.makefile()
        cPickle.dump((self.name, args, kwargs), f)
        '''cPickle.dump(self.name,f)
        cPickle.dump(args,f)     
        cPickle.dump(kwargs,f)'''   
        f.flush()
        res = cPickle.load(f)
        s.close()
        return res

def machine_changed_signal(machine):
    HOST = ''
    PORT = 50000
    SERVER_ADDRESS = HOST, PORT
    advise = RemoteFunction(SERVER_ADDRESS,'changes')
    advise(machine)

运行时,我遇到了以下错误信息:

Traceback (most recent call last):
  File "/home/manch011/disserver/src/disserver/gui/backends/receiver.py", line 71, in run
    args = cPickle.load(connFile)
cPickle.UnpicklingError: pickle data was truncated

在我做了一些修改后,现在我又遇到了以下错误信息:

Traceback (most recent call last):
File "/home/manch011/disserver/src/disserver/gui/backends/receiver.py", line 69, in run
name, args, kwargs = cPickle.load(connFile)
EOFError

我对cPickle不太熟悉,所以搞不清楚这个问题,有人能给我解释一下吗?

提前谢谢你们!

1 个回答

3

当你把一个套接字(socket)变成一个像文件一样的对象时(用 connFile = conn.makefile() 这行代码),你在套接字里所有的数据都可以在这个文件里找到。当你第一次使用 cPickle.load(connFile) 时,套接字/文件里的所有内容都会被加载到内存中。所以在第二次调用的时候,就没有东西可以再解码了,这就是为什么 pickle 会报错的原因。

所有的数据在第一次调用 cPickle.load(connFile) 时就已经被解码了。如果你想提取一个函数名、参数和关键字参数,可以尝试发送一个包含这些数据的元组:

客户端代码:

cPickle.dump((function_name, args, kwargs), client_socket_as_file)

服务器端代码:

name, args, kwargs = cPickle.load(connFile)

撰写回答