cPickle.UnpicklingError: данные pickle были усечены - PullRequest
2 голосов
/ 21 ноября 2011

Я использую вызов удаленной процедуры для связи между двумя процессами.Я отправляю предметы из рук в руки другому.объект является объектом по модели Джанго.Объект имеет разные переменные, целые числа и строки.

Если я изменяю только целочисленные переменные, все работает нормально.если я изменяю строковую переменную в первый раз, она тоже работает, но если я изменяю строку во второй раз, мой код падает, и я получаю следующее сообщение об ошибке

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)
cPickle.UnpicklingError: pickle data was truncated

Это мой код на сервере.side:

_exportedMethods = {
    'changes': signal_when_changes,
}  

class ServerThread(QtCore.QThread):

    def __init__(self):
        super(ServerThread,self).__init__()
        st = self
    #threading.Thread.__init__(self)
    def run(self):
        HOST = ''     # local host
        PORT = 50000
        SERVER_ADDRESS = HOST, PORT

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

        while True:
            conn, addr = s.accept()
            connFile = conn.makefile()
            name, args, 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) 
    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)

Я не знаком с cPickle и, следовательно, не могу понять это, может кто-нибудь объяснить мне это?

Заранее спасибо Чис

1 Ответ

1 голос
/ 22 ноября 2011

Я решил свою проблему. Но сначала сообщение об ошибке, которое я опишу в своем вопросе, не имеет смысла.

Я решил новую проблему и использовал Pyro4 Framework. Таким образом, я получил новое сообщение об ошибке, которое было эквивалентно старому, но ясно. Вы не можете мариновать объекты класса. Поскольку в моем случае мне нужны только значения атрибутов, я передаю это в простом словаре.

Сначала скачайте Pyro4 и установите его Простой пример, подобный примеру на домашней странице Pyro :

# saved as helloworld.py
import Pyro4
import threading
import os
class HelloWorld(object):
    def get_hello_world(self, name):
        return "HelloWorld,{0}.".format(name)

#The NameServer had to run in a own thread because he has his own eventloop
class NameServer(threading.Thread):
    def __init__(self):
    threading.Thread.__init__(self)
    def run(self):
    os.system("python -m Pyro4.naming")
ns = NameServer()
ns.start()
hello_world=HelloWorld()
daemon=Pyro4.Daemon()                 # make a Pyro daemon
ns=Pyro4.locateNS()                   # find the name server
uri=daemon.register(hello_world)   # register the greeting object as a Pyro object
ns.register("example.helloworld", uri)  # register the object with a name in the name server
print "Ready."
daemon.requestLoop()                  # start the event loop of the server to wait for calls

запустить эту программу и выполнить следующую после

# saved as client.py
import Pyro4
name=raw_input("What is your name? ").strip()
helloworld=Pyro4.Proxy("PYRONAME:example.helloworld")    # use name server object lookup uri shortcut
print helloworld.get_hello_world(name)

Внимание! Вы не можете передавать экземпляры классов. Поэтому «имя» не может быть экземпляром класса.

...