3

我尝试在 Python 中使用 XMLRPC 创建一个简单的下载和上传系统

这是客户端的代码(将此文件命名为client.py)

import sys
import xmlrpclib
import os

def return_pause():
    """Used for creating a pause during input"""

    raw_input("\n\tPress enter to continue")

def mod_file_download(file_name, local_port, remote_proxy, local_proxy):
    """Sending details to remote node which will send file to local node"""

    #print "till here"

    #print "{%s}\t{%s}" % (file_name,local_proxy)

    remote_proxy.mod_file_transfer(file_name, local_proxy)

def mod_file_upload(file_path, file_name, remote_proxy):
    """Used for sending files to a receiver. Sent file will always have the name file_1.txt"""

    new_file_name = "file_1.txt"
    with open(file_path, "rb") as handle:
        bin_data = xmlrpclib.Binary(handle.read())

    remote_proxy.mod_file_receive(bin_data, new_file_name)

    return True

##MAIN MODULE STARTS HERE##

# Connection details of remote node
local_port = sys.argv[1]

# Getting details of remote node
remote_port = raw_input("\n\tEnter remote port ID : ")

# Creating connection details of remote node
remote_proxy = xmlrpclib.ServerProxy("http://localhost:" + remote_port + "/")

# Creating connection details of local node
local_proxy = xmlrpclib.ServerProxy("http://localhost:" + local_port + "/")

while True:
    os.system('clear')

    print "\t. : Collab Menu for %s : .\n" % local_port
    print "\tSearch & download ...[1]"
    print "\tUpload            ...[2]"
    print "\tExit              ...[0]"

    input_val = raw_input("\n\n\tEnter option : ")

    if input_val == "1":
        file_name = raw_input("\n\tEnter name of file to be downloaded : ")

        mod_file_download(file_name, local_port, remote_proxy, local_proxy)

        return_pause()

    elif input_val == "2":
        file_name = raw_input("\n\tEnter name of file to be uploaded : ")

        file_path = "./" + file_name

        mod_file_upload(file_path, file_name, remote_proxy, local_proxy)

        return_pause()

    elif input_val == "0":
        print "\tExiting"
        break

    else:
        print "\tIncorrect option value"
        print "\tTry again..."
        return_pause()

os.system('clear')

这是监听器的代码(将此文件命名为 listener.py)

import sys
import xmlrpclib
from SimpleXMLRPCServer import SimpleXMLRPCServer

def mod_file_transfer(file_name, requestor_proxy):
    """Initiating the file transfer"""

    print "[mod_file_transfer fired]"

    file_path = "./" + file_name

    print requestor_proxy

    with open(file_path, "rb") as handle:
        bin_data = xmlrpclib.Binary(handle.read())

    # Connecting to requestor's server
    requestor_proxy.mod_file_download_receive(bin_data, file_name)

    return True

def mod_file_receive(bin_data, file_name):
    """Used to receive a file upon a request of an upload"""

    print "[mod_file_receive fired]"

    new_file_name = "./" + file_name
    with open(new_file_name, "wb") as handle:
        handle.write(bin_data.data)
        return True

def mod_file_download_receive(bin_data, file_name):
    """Used to receive a file upon request of a download"""

    print "[mod_file_download_receive fired]"

    new_file_name = "./" + file_name + str(1)
    with open(new_file_name, "wb") as handle:
        handle.write(bin_data.data)
        return True

##MAIN MODULE STARTS HERE##

local_port = sys.argv[1]

# Declared an XMLRPC server
node = SimpleXMLRPCServer(("localhost", int(local_port)), logRequests=True, allow_none=True)
print "Listening on port %s..." % local_port

# Registered a list of functions
node.register_function(mod_file_transfer, 'mod_file_transfer')
node.register_function(mod_file_receive, 'mod_file_receive')
node.register_function(mod_file_download_receive, 'mod_file_download_receive')

# Initialized the XMLRPC server
node.serve_forever()

如何启动系统?

  1. 将两个文件放在同一个目录下
  2. 执行以下命令
  3. 蟒蛇监听器9000
  4. 蟒蛇监听器9500
  5. python客户端9000(然后将远程客户端端口作为9500作为输入)
  6. python客户端9500(然后将远程客户端端口作为9000作为输入)

文件上传工作正常

但是文件下载不起作用

它给了我以下错误

Traceback (most recent call last):
  File "collab_client.py", line 57, in <module>
    mod_file_download(file_name, local_port, remote_proxy, local_proxy)
  File "collab_client.py", line 17, in mod_file_download
    remote_proxy.mod_file_transfer(file_name, local_proxy)
  File "/usr/lib/python2.7/xmlrpclib.py", line 1240, in __call__
    return self.__send(self.__name, args)
  File "/usr/lib/python2.7/xmlrpclib.py", line 1593, in __request
    allow_none=self.__allow_none)
  File "/usr/lib/python2.7/xmlrpclib.py", line 1091, in dumps
    data = m.dumps(params)
  File "/usr/lib/python2.7/xmlrpclib.py", line 638, in dumps
    dump(v, write)
  File "/usr/lib/python2.7/xmlrpclib.py", line 660, in __dump
    f(self, value, write)
  File "/usr/lib/python2.7/xmlrpclib.py", line 762, in dump_instance
    self.dump_struct(value.__dict__, write)
  File "/usr/lib/python2.7/xmlrpclib.py", line 741, in dump_struct
    dump(v, write)
  File "/usr/lib/python2.7/xmlrpclib.py", line 660, in __dump
    f(self, value, write)
  File "/usr/lib/python2.7/xmlrpclib.py", line 762, in dump_instance
    self.dump_struct(value.__dict__, write)
  File "/usr/lib/python2.7/xmlrpclib.py", line 741, in dump_struct
    dump(v, write)
  File "/usr/lib/python2.7/xmlrpclib.py", line 660, in __dump
    f(self, value, write)
  File "/usr/lib/python2.7/xmlrpclib.py", line 720, in dump_array
    dump(v, write)
  File "/usr/lib/python2.7/xmlrpclib.py", line 660, in __dump
    f(self, value, write)
  File "/usr/lib/python2.7/xmlrpclib.py", line 664, in dump_nil
    raise TypeError, "cannot marshal None unless allow_none is enabled"
TypeError: cannot marshal None unless allow_none is enabled

但我已经allow_none=True在监听器文件中给出了选项。

我哪里错了?

4

1 回答 1

1

我很头疼之后才找到它。似乎无法发送或编组连接详细信息。在函数中mod_file_transfer,我尝试将客户端连接详细信息作为对象发送(以便服务器知道它必须将文件发送给谁),这导致了错误。

我只是将客户端连接详细信息作为字符串发送,它就可以工作。谢谢我!

于 2016-04-01T10:19:16.613 回答