Python XML-RPC服务器跨机访问失败及多客户端支持问题
问题描述
- 使用Python XML-RPC编写的服务器无法从外部计算机访问,客户端连接时出现超时错误
- 希望配置服务器支持多客户端同时连接
服务器端代码
from xmlrpc.server import SimpleXMLRPCServer from xmlrpc.server import SimpleXMLRPCRequestHandler # Restrict to a particular path. class RequestHandler(SimpleXMLRPCRequestHandler): rpc_paths = ('/RPC2',) # Create server with SimpleXMLRPCServer(('82.155.18.86', 8000), requestHandler=RequestHandler) as server: 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') # Register an instance; all the methods of the instance are # published as XML-RPC methods (in this case, just 'mul'). class MyFuncs: def mul(self, x, y): return x * y server.register_instance(MyFuncs()) # Run the server's main loop server.serve_forever()
客户端代码(运行在其他计算机)
import xmlrpc.client s = xmlrpc.client.ServerProxy('http://82.155.18.86:8000') print(s.pow(2,3)) # Returns 2**3 = 8 print(s.add(2,3)) # Returns 5 print(s.mul(5,2)) # Returns 5*2 = 10 # Print list of available methods print(s.system.listMethods())
报错信息
C:\Users\Nima\PycharmProjects\RPC\venv\Scripts\python.exe C:/Users/Nima/PycharmProjects/RPC/main.py Traceback (most recent call last): File "C:\Users\Nima\PycharmProjects\RPC\main.py", line 4, in <module> print(s.pow(2,3)) # Returns 2**3 = 8 File "C:\Users\Nima\AppData\Local\Programs\Python\Python39\lib\xmlrpc\client.py", line 1116, in __call__ return self.__send(self.__name, args) File "C:\Users\Nima\AppData\Local\Programs\Python\Python39\lib\xmlrpc\client.py", line 1456, in __request response = self.__transport.request( File "C:\Users\Nima\AppData\Local\Programs\Python\Python39\lib\xmlrpc\client.py", line 1160, in request return self.single_request(host, handler, request_body, verbose) File "C:\Users\Nima\AppData\Local\Programs\Python\Python39\lib\xmlrpc\client.py", line 1172, in single_request http_conn = self.send_request(host, handler, request_body, verbose) File "C:\Users\Nima\AppData\Local\Programs\Python\Python39\lib\xmlrpc\client.py", line 1285, in send_request self.send_content(connection, request_body) File "C:\Users\Nima\AppData\Local\Programs\Python\Python39\lib\xmlrpc\client.py", line 1315, in send_content connection.endheaders(request_body) File "C:\Users\Nima\AppData\Local\Programs\Python\Python39\lib\http\client.py", line 1250, in endheaders self._send_output(message_body, encode_chunked=encode_chunked) File "C:\Users\Nima\AppData\Local\Programs\Python\Python39\lib\http\client.py", line 1010, in _send_output self.send(msg) File "C:\Users\Nima\AppData\Local\Programs\Python\Python39\lib\http\client.py", line 950, in send self.connect() File "C:\Users\Nima\AppData\Local\Programs\Python\Python39\lib\http\client.py", line 921, in connect self.sock = self._create_connection( File "C:\Users\Nima\AppData\Local\Programs\Python\Python39\lib\socket.py", line 843, in create_connection raise err File "C:\Users\Nima\AppData\Local\Programs\Python\Python39\lib\socket.py", line 831, in create_connection sock.connect(sa) TimeoutError: [WinError 10060] A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond Process finished with exit code 1
解决方案
一、解决外部连接超时问题
连接超时基本是网络层面的问题,按以下步骤排查修复:
修改服务器绑定地址
当前服务器绑定了固定IP82.155.18.86,如果该IP不是服务器公网IP或服务器有多个网卡,会导致外部无法访问。改为绑定所有可用地址0.0.0.0:with SimpleXMLRPCServer(('0.0.0.0', 8000), requestHandler=RequestHandler) as server:开放端口权限
- 检查服务器本地防火墙,允许8000端口的TCP入站连接
- 如果是云服务器,需在云服务商的安全组中添加8000端口的入站规则
验证端口连通性
在客户端计算机上,使用telnet 82.155.18.86 8000或nc -zv 82.155.18.86 8000测试端口是否能连通,若测试失败,优先排查防火墙/安全组配置确认公网IP正确性
确保客户端使用的IP是服务器的公网IP,可在服务器上通过curl ifconfig.me(Linux)或在线IP查询工具获取公网IP
二、配置服务器支持多客户端同时连接
默认SimpleXMLRPCServer是单线程,同一时间只能处理一个请求,可通过以下两种方式实现多客户端支持:
方法1:多线程服务器(通用方案)
使用Python内置的ThreadingSimpleXMLRPCServer,为每个客户端请求创建独立线程:
from xmlrpc.server import ThreadingSimpleXMLRPCServer from xmlrpc.server import SimpleXMLRPCRequestHandler class RequestHandler(SimpleXMLRPCRequestHandler): rpc_paths = ('/RPC2',) with ThreadingSimpleXMLRPCServer(('0.0.0.0', 8000), requestHandler=RequestHandler) as server: server.register_introspection_functions() # 注册函数、实例的代码保持不变 server.serve_forever()
方法2:多进程服务器(仅Linux/Unix,适合CPU密集型任务)
通过ForkingMixIn实现多进程处理,每个请求分配独立进程:
from xmlrpc.server import SimpleXMLRPCServer from xmlrpc.server import SimpleXMLRPCRequestHandler from socketserver import ForkingMixIn class ForkingXMLRPCServer(ForkingMixIn, SimpleXMLRPCServer): pass class RequestHandler(SimpleXMLRPCRequestHandler): rpc_paths = ('/RPC2',) with ForkingXMLRPCServer(('0.0.0.0', 8000), requestHandler=RequestHandler) as server: server.register_introspection_functions() # 注册函数、实例的代码保持不变 server.serve_forever()
注意:Windows系统不支持ForkingMixIn,优先使用多线程方案。
内容的提问来源于stack exchange,提问作者Nima
相关产品推荐
相关产品推荐

