Python的xmlrpc库基于XML和HTTP实现轻量级RPC,服务端用xmlrpc.server(原SimpleXMLRPCServer),支持线程安全与introspection;客户端用ServerProxy调用远程方法,需注意路径、方法名及类型限制。

Python 的 xmlrpc 库(标准库中的 xmlrpc.client 和 xmlrpc.server)用于实现轻量级的远程过程调用(RPC),基于 XML 编码和 HTTP 传输。它适合简单服务交互,无需复杂协议或依赖第三方包。
XML-RPC 服务端:用 SimpleXMLRPCServer(Python 3.12+ 已弃用,推荐用 xmlrpc.server)
Python 3.3+ 中,SimpleXMLRPCServer 已移入 xmlrpc.server 模块,且支持线程安全(默认单线程,可搭配 ThreadingMixIn 支持并发)。
示例服务端(支持加法、获取时间):
立即学习“Python免费学习笔记(深入)”;
from xmlrpc.server import SimpleXMLRPCServer
from xmlrpc.server import SimpleXMLRPCRequestHandler
import datetime
<h1>可选:限制只响应特定路径(增强安全性)</h1><p>class RequestHandler(SimpleXMLRPCRequestHandler):
rpc_paths = ('/RPC2',)</p><p>def add(x, y):
return x + y</p><p>def get_time():
return datetime.datetime.now().isoformat()</p><h1>创建服务器,监听本地 8000 端口</h1><p>server = SimpleXMLRPCServer(('localhost', 8000), requestHandler=RequestHandler)
server.register_function(add, 'calc.add')
server.register_function(get_time, 'system.time')</p><h1>可选:注册内置系统方法(如 system.listMethods)</h1><p>server.register_introspection_functions()</p><p>print("XML-RPC server running on <a href="https://www.php.cn/link/464d0b9d99efb7a4595380d03b7ea164">https://www.php.cn/link/464d0b9d99efb7a4595380d03b7ea164</a>")
try:
server.serve_forever()
except KeyboardInterrupt:
print("\nShutting down server.")
说明:
-
register_function(func, name)将函数暴露为远程可调用方法,name是客户端调用时用的名称(如calc.add) -
register_introspection_functions()启用system.listMethods、system.methodHelp等调试方法 - 若需多线程处理并发请求,可继承
ThreadingMixIn:
from socketserver import ThreadingMixIn
<p>class ThreadedXMLRPCServer(ThreadingMixIn, SimpleXMLRPCServer):
pass</p><p>server = ThreadedXMLRPCServer(('localhost', 8000'))
XML-RPC 客户端:用 xmlrpc.client.ServerProxy
客户端通过 URL 创建代理对象,像调用本地函数一样调用远程方法。
import xmlrpc.client
<h1>连接服务端(注意路径 /RPC2 必须和服务端一致)</h1><p>proxy = xmlrpc.client.ServerProxy('<a href="https://www.php.cn/link/464d0b9d99efb7a4595380d03b7ea164">https://www.php.cn/link/464d0b9d99efb7a4595380d03b7ea164</a>')</p><h1>调用远程方法(自动序列化/反序列化)</h1><p>result = proxy.calc.add(10, 20)
print("10 + 20 =", result) # 输出:10 + 20 = 30</p><p>time_str = proxy.system.time()
print("Server time:", time_str)</p><h1>查看可用方法(需服务端启用了 introspection)</h1><p>methods = proxy.system.listMethods()
print("Available methods:", methods)
关键点:
- URL 必须包含完整路径(如
/RPC2),否则会返回 404 - 方法名按点号层级调用(
proxy.calc.add对应服务端注册的'calc.add') - 支持基本类型:int、float、str、bool、list、dict、datetime(自动转为 ISO 格式字符串)、None
- 不支持自定义类、函数、字节流等;二进制数据需用
xmlrpc.client.Binary包装
传输二进制数据(如图片、文件内容)
XML-RPC 原生不支持 raw bytes,需用 Binary 类封装:
# 服务端增加方法
def upload_data(data_bin):
data = data_bin.data # 获取 bytes
print(f"Received {len(data)} bytes")
return len(data)
<p>server.register_function(upload_data, 'file.upload')</p><h1>客户端调用</h1><p>with open('test.bin', 'rb') as f:
binary_data = xmlrpc.client.Binary(f.read())
proxy.file.upload(binary_data)
常见问题与注意事项
-
Python 版本差异:Python 3.12+ 已完全移除
SimpleXMLRPCServer别名,必须从xmlrpc.server导入 -
异常处理:网络错误或服务端异常会抛出
xmlrpc.client.Fault或ConnectionError,建议 try/except 包裹调用 - 编码限制:所有字符串必须是 UTF-8 兼容(Python str 默认满足),含控制字符可能失败
- 性能与替代方案:XML-RPC 解析较慢,不适用于高频或大数据量场景;现代项目更倾向 REST(Flask/FastAPI)或 gRPC
不复杂但容易忽略:确保服务端和客户端使用相同路径、方法名大小写一致、参数类型在 XML-RPC 支持范围内。调试时先用 system.listMethods 确认接口可达。










