Twisted开发简单协议时出现Connection refused连接被拒错误
错误产生原因
- 直接触发
ConnectionRefusedError的原因:目标地址127.0.0.1:8050没有处于监听状态的TCP服务,操作系统内核直接拒绝了本次TCP连接请求,错误码61是类Unix系统对「连接被对端拒绝」的标准返回码。 - 代码本身存在固有逻辑缺陷:即便8050端口有服务监听,代码也会运行崩溃。Twisted框架中,
Protocol实例执行__init__方法时,还未完成和底层传输对象(transport)的绑定,此时self.transport值为None,在__init__中直接调用self.transport.write()、self.transport.loseConnection()、self.transport.getPeer()都会触发NoneType对象的属性访问异常。另外代码中导入的task、TCP4ClientEndpoint、connectProtocol均未使用,属于冗余导入。
修复方案
- 首先确保本地
127.0.0.1:8050有正常运行的TCP监听服务。你可以先运行如下测试服务端代码,验证端口连通性:
from twisted.internet import protocol, reactor class SimpleTestServer(protocol.Protocol): def connectionMade(self): print("服务端收到客户端连接请求") self.transport.write(b"hello from test server") def dataReceived(self, data): print(f"服务端收到客户端数据: {data.decode('utf-8')}") class TestServerFactory(protocol.Factory): def buildProtocol(self, addr): return SimpleTestServer() # 监听本地8050端口 reactor.listenTCP(8050, TestServerFactory()) reactor.run()
- 修正客户端Protocol类的生命周期逻辑:所有涉及
self.transport的操作,必须放到connectionMade回调方法中执行——该方法是Twisted框架在TCP连接建立完成、Protocol实例和transport成功绑定后才会触发的生命周期钩子,不要在__init__方法中访问transport对象。修正后的客户端代码如下:
from twisted.internet import protocol, reactor from twisted.internet.protocol import ClientFactory class TestClass(protocol.Protocol): def connectionMade(self): # 连接建立完成后再操作transport print(f"成功连接到对端地址: {self.transport.getPeer()}") self.transport.write(b"Connect to the transport") # 测试完成后断开连接 self.transport.loseConnection() def dataReceived(self, data): print(f"收到服务端响应: {data.decode('utf-8')}") class EchoClientFactory(ClientFactory): def startedConnecting(self, connector): print('Started to connect.') def buildProtocol(self, addr): print('Connected.') return TestClass() def clientConnectionLost(self, connector, reason): print('Lost connection. Reason:', reason) reactor.stop() def clientConnectionFailed(self, connector, reason): print('Connection failed. Reason:', reason) reactor.stop() if __name__ == "__main__": reactor.connectTCP('127.0.0.1', 8050, EchoClientFactory()) reactor.run()
- 运行顺序:先启动测试服务端,再启动客户端,即可看到正常的连接、数据交互、断开日志,不会再出现连接拒绝报错。
内容的提问来源于stack exchange,提问作者Emil11
相关产品推荐
相关产品推荐

