如何获取XMLRPC服务器的输出(Python 2.7.3)?

3 投票
1 回答
5984 浏览
提问于 2025-04-17 19:39

我从Python官网上获取了XMLRPC的服务器和客户端。当我在Windows上运行一些简单的方法,比如pow()、add()、div()时,客户端能正确收到结果。然而,当我运行brocade()这个方法时,它会从Brocade交换机获取配置信息,使用Python模块(PyCrypto、Paramiko),并返回一个字符串输出,这个过程大约需要2-3秒(具体时间可能更长,取决于交换机命令)。我观察到服务器执行得很正常,并且打印了输出,但客户端却收到了一条类似下面的消息。

C:\CVS\Python\MyTestProject\src>python xmlrpcclient2.py
8
5
2
Traceback (most recent call last):
  File "xmlrpcclient2.py", line 8, in <module>
    print s.brocade('sh ver')
  File "c:\Python27\lib\xmlrpclib.py", line 1224, in __call__
    return self.__send(self.__name, args)
  File "c:\Python27\lib\xmlrpclib.py", line 1578, in __request
    verbose=self.__verbose
  File "c:\Python27\lib\xmlrpclib.py", line 1264, in request
    return self.single_request(host, handler, request_body, verbose)
  File "c:\Python27\lib\xmlrpclib.py", line 1297, in single_request
    return self.parse_response(response)
  File "c:\Python27\lib\xmlrpclib.py", line 1473, in parse_response
    return u.close()
  File "c:\Python27\lib\xmlrpclib.py", line 793, in close
    raise Fault(**self._stack[0])
xmlrpclib.Fault: <Fault 1: "<type 'exceptions.TypeError'>:cannot marshal None unless allow_none is enabled">

服务器显示

T06CORE - - [19/Mar/2013 11:11:33] "POST /RPC2 HTTP/1.1" 200 -
T06CORE - - [19/Mar/2013 11:12:04] "POST /RPC2 HTTP/1.1" 200 -
T06CORE - - [19/Mar/2013 11:12:05] "POST /RPC2 HTTP/1.1" 200 -
T06CORE - - [19/Mar/2013 11:12:06] "POST /RPC2 HTTP/1.1" 200 -
All jobs enqueued.
Waiting for the queue to finish.



You have reached Brocade FCF195


   cmsh
gets you into the IOS-style management shell.
-----------------------------------------------------------------
broc150_jack:admin> switchshow | grep switchType
switchType:     76.7
broc150_jack:admin> cmsh
broc150_jack#sh ver
←[?1h←=←[K            Fabric Operating System Software
Fabric Operating System Version: 7.0
Copyright (c) 1995-2008 Brocade Communications Systems, Inc.
Build Time: 21:52:25 Oct 10, 2012
broc150_jack uptime: 12w4d19h
Firmware name: v7.0.2a

Switch Model Name: Brocade 8000
Control Processor: Freescale Semiconductor 8548E with 1016 MB of memory

4MB of boot flash memory.

  8 FC Port(s)
 24 Ten GigabitEthernet/IEEE 802.3 interface(s)
←[K            ←[?1l←>broc150_jack#10.0.0.150 job is done.
Destroying queue...
Queue destroyed.
T06CORE - - [19/Mar/2013 11:12:08] "POST /RPC2 HTTP/1.1" 200 -

你知道客户端怎么才能获取到brocade()的结果吗?

谢谢,

Spark。

xmlrpcserver2.py

from SimpleXMLRPCServer import SimpleXMLRPCServer
from SimpleXMLRPCServer import SimpleXMLRPCRequestHandler

# Restrict to a particular path.
class RequestHandler(SimpleXMLRPCRequestHandler):
rpc_paths = ('/RPC2',)

# Create server
listening_port = 8002
server = SimpleXMLRPCServer(("localhost", listening_port),
                           requestHandler=RequestHandler)
print "Listening on port %d..." % listening_port
server.register_multicall_functions()                           
server.register_introspection_functions()

# Register pow() function; this will use the value of
# pow.__name__ as the name, which is just 'pow'.
server.register_function(pow)

# Register a function under a different name
def adder_function(x,y):
    return x + y
server.register_function(adder_function, 'add')

def brocade(str):
    import brocade
    return brocade.MySwitch().do_something_cool(str)
server.register_function(brocade, 'brocade')

# Register an instance; all the methods of the instance are
# published as XML-RPC methods (in this case, just 'div').
class MyFuncs:
    def div(self, x, y):
        return x // y
server.register_instance(MyFuncs())

# Run the server's main loop
server.serve_forever()

xmlrpcclient2.py

import xmlrpclib

s = xmlrpclib.ServerProxy('http://localhost:8002')

print s.pow(2,3)  # Returns 2**3 = 8
print s.add(2,3)  # Returns 5
print s.div(5,2)  # Returns 5//2 = 2
print s.brocade('sh ver')

1 个回答

3

XMLRPC技术上是不允许空值的,当你试图把一个None(表示没有值)进行序列化时,它会正确地告诉你不能这样做。不过,很多xmlrpc服务并没有遵循这个规则,还是发送了空值,而且这种做法是大家都能理解的。为了在Python中实现这种行为,你需要在服务器代码中给SimpleXMLRPCServer()的构造函数里加上allow_none=True,或者在客户端的ServerProxy()里加上这个参数。

server = SimpleXMLRPCServer(("localhost", listening_port),
                            requestHandler=RequestHandler,
                            allow_none=True) 

还有

s = xmlrpclib.ServerProxy('http://localhost:8002', allow_none=True)

撰写回答