千家信息网

python中怎么利用twisted实现TCP通讯

发表于:2026-11-04 作者:千家信息网编辑
千家信息网最后更新 2026年11月04日,这期内容当中小编将会给大家带来有关python中怎么利用twisted实现TCP通讯,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。0.写在前面不管是服务器端还是客户
千家信息网最后更新 2026年11月04日python中怎么利用twisted实现TCP通讯

这期内容当中小编将会给大家带来有关python中怎么利用twisted实现TCP通讯,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。

0.写在前面

不管是服务器端还是客户端,都是通过twisted的reactor来启动的,所以首先就需要导入twisted.internet包下的reactor模块

从reactor模块的源码中可以看出reactor模块其实是由多个接口组成的,并且提示了具体内容需要查看twisted.internet包下的interfaces模块中每个接口的具体注释说明

当然从reactor模块的注释中也说明了twisted不止可以用于TCP服务,而是提供了网络方面的API、线程、调度等功能, 但是本次的实验仅仅测试一下TCP的服务器端和客户端

reactor注释中提到的支持的接口:@see: L{IReactorCore}@see: L{IReactorTime}@see: L{IReactorProcess}@see: L{IReactorTCP}@see: L{IReactorSSL}@see: L{IReactorUDP}@see: L{IReactorMulticast}@see: L{IReactorUNIX}@see: L{IReactorUNIXDatagram}@see: L{IReactorFDSet}@see: L{IReactorThreads}@see: L{IReactorPluggableResolver}

1.TCP服务器端

·reactor反应器

根据上面reactor模块的注释,发现和TCP相关的需要查看interfaces模块下的IReactorTCP接口,所以接下来我们移步至IReactorTCP接口

IReactorTCP接口中有两个方法listenTCP和connectTCP,不管从方法名还是其说明都可以看出,前者是监听一个端口提供TCP服务,后者是连接到服务端的TCP客户端

def listenTCP(port, factory, backlog=50, interface=''):def connectTCP(host, port, factory, timeout=30, bindAddress=None):

所以要开启一个TCP服务端,我们需要用到的是listenTCP方法,这个方法有4个参数

参数名意义默认值
port监听的端口,也就是TCP服务启动的端口-
factory服务端的工厂类(根据注释中的提示:详情见twisted.internet包下的protocol模块中的ServerFactory类)-
backlog监听队列,响应线程数50
interface要绑定到的本地IPv4或IPv6地址,默认为空标示所有IPv4的地址''

·Factory工厂类

在设置了前两个参数以后,然后通过下面两行代码就可以启动TCP服务了

reactor.listenTCP(port, ServerFactory())reactor.run()

但是,此时启动的服务是有问题的,当有客户端连接到该服务的时候就会报错

---  ---  File "D:\MyWorkSpaces\tools\Anaconda3\envs\tf2\lib\site-packages\twisted\internet\tcp.py", line 1427, in doRead    self._buildAddr(addr))  File "D:\MyWorkSpaces\tools\Anaconda3\envs\tf2\lib\site-packages\twisted\internet\protocol.py", line 140, in buildProtocol    p = self.protocol()builtins.TypeError: 'NoneType' object is not callable

根据错误提示,我们找到了问题的原因:

在客户端连接到服务器端的时候,会调用Factory类(ServerFactory的父类)中的buildProtocol方法来建立通讯协议(这里可以理解为客户端和服务器端之间读写的实现方法),其中需要调用self.protocol所指向的方法来初始化这个协议

然而此时的protocol却是None,所以在协议的初始化阶段出错了

·Protocol协议类

再次研究一下protocol模块中的Factory类,发现类方法forProtocol是用于创建factory实例的,但是需要给定一个protocol实例

很好,我们的目标又近了一步,下面继续研究Protocol类

同样在protocol模块中,我们找到了Protocol类,他继承自BaseProtocol类,总共有下面几个方法

  • BaseProtocol.makeConnection:用于开启连接,当连接开启后会回调connectionMade方法

  • BaseProtocol.connectionMade:未实现。当连接成功以后回调该方法

  • Protocol.logPrefix:返回当前类的类名,用于日志log

  • Protocol.dataReceived:未实现。当收到请求时被调用的方法

  • Protocol.connectionLost:未实现。当连接断开时调用的方法

所以现在我们只要继承Protocol类,写一个自己的实现协议就可以了,并且只需要实现父类中未实现的3个方法

为了简单一些,在connectionMade和connectionLost方法中我们只记录一下客户端的连接信息并输出一下log,而在dataReceived方法中我们将收到的信息打印出来,并在5s过后返回客户端一条消息

class TcpServer(Protocol)::    CLIENT_MAP = {}  # 用于保存客户端的连接信息    def connectionMade(self):        addr = self.transport.client  # 获取客户端的连接信息        print("connected", self.transport.socket)        TcpServer.CLIENT_MAP[addr] = self    def connectionLost(self, reason):        addr = self.transport.client  # 获取客户端的连接信息        if addr in TcpServer.CLIENT_MAP:            print(addr, "Lost Connection from Tcp Server", 'Reason:', reason)            del TcpServer.CLIENT_MAP[addr]    def dataReceived(self, tcp_data):        addr = self.transport.client  # 获取客户端的连接信息        nowTime = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')        try:            msg = tcp_data.decode("utf-8")            print("Received msg", msg, "from Tcp Client", addr)            time.sleep(5)            str = "来自服务器的响应 " + nowTime            self.transport.write(str.encode("utf-8"))        except BaseException as e:            print("Comd Execute Error from", addr, "data:", tcp_data)            str = "服务器发生异常 " + nowTime            self.transport.write(str.encode("utf-8"))

·启动TCP服务

好,Protocol类已经实现了,我们用他来创建工厂实例并启动TCP服务

    port = 9527    serverFactory = Factory.forProtocol(TcpServer)    reactor.listenTCP(port, serverFactory)    print("#####", "Starting TCP Server on", port, "#####")    reactor.run()

TCP服务成功启动,并且客户端连接上来以后也没有报错

D:\MyWorkSpaces\tools\Anaconda3\envs\tf2\python.exe D:/MyWorkSpaces/projects/all/sample/python/twisted/server.py##### Starting TCP Server on 9527 #####connected Received msg 你好服务器,我是客户端 2019-08-10 11:13:09 from Tcp Client ('127.0.0.1', 3440)

2.TCP客户端

·reactor反应器

有了服务器的经验,我们回来看reactor模块中IReactorTCP接口里的connectTCP方法,这个方法一共有5个参数

参数名意义默认值
host服务器地址,IPv4或IPv6-
prot服务器端口-
factory客户端的工厂类,(根据注释中的提示:详情见twisted.internet包下的protocol模块中的ClientFactory类)-
timeout连接超时时间,单位s30
bindAddress本地的地址,格式为(host,port)的元祖None

同样也很简单,我们只要以下两行代码就可以启动客户端了,但是和服务端类似,在这之前我们也需要实现一个Factory工厂类和Protocol协议类的实例

reactor.connectTCP(host, port, factory)reactor.run()

·Factory工厂类

根据connectTCP方法的注释说明,我们直接可以找到ClientFactory类,类中有3个方法需要实现

  • ClientFactory.startedConnecting:未实现。开启连接时会调用该方法

  • ClientFactory.clientConnectionFailed:未实现。连接失败时会调用该方法

  • ClientFactory.clientConnectionLost:未实现。连接断开时会调用该方法

同样,为了简单,我们在startedConnecting方法中只做一下日志log的记录,在clientConnectionFailed和clientConnectionLost方法中记录入职log以后隔30s以后重试连接

class TcpClientFactory(ClientFactory):    def startedConnecting(self, connector):        print("Starting Connecting To Tcp Server", (connector.host, connector.port))    def clientConnectionLost(self, connector, reason):        print("Lost Connection from Tcp Server", (connector.host, connector.port), 'Reason:', reason)        time.sleep(30)        connector.connect()    def clientConnectionFailed(self, connector, reason):        print("Failed To Connect To Tcp Server", (connector.host, connector.port), 'Reason:', reason)        time.sleep(30)        connector.connect()

启动TCP客户端,我们发现了和第一次启动服务端时一样的错误,这次我们有经验了,因为少了Protocol类的实现

---  ---  File "D:\MyWorkSpaces\tools\Anaconda3\envs\tf2\lib\site-packages\twisted\internet\selectreactor.py", line 149, in _doReadOrWrite    why = getattr(selectable, method)()  File "D:\MyWorkSpaces\tools\Anaconda3\envs\tf2\lib\site-packages\twisted\internet\tcp.py", line 627, in doConnect    self._connectDone()  File "D:\MyWorkSpaces\tools\Anaconda3\envs\tf2\lib\site-packages\twisted\internet\tcp.py", line 641, in _connectDone    self.protocol = self.connector.buildProtocol(self.getPeer())  File "D:\MyWorkSpaces\tools\Anaconda3\envs\tf2\lib\site-packages\twisted\internet\base.py", line 1157, in buildProtocol    return self.factory.buildProtocol(addr)  File "D:\MyWorkSpaces\tools\Anaconda3\envs\tf2\lib\site-packages\twisted\internet\protocol.py", line 140, in buildProtocol    p = self.protocol()builtins.TypeError: 'NoneType' object is not callable

·Protocol协议类

和服务器端使用的是同一个Protocol父类,这里稍微做点和服务器端不同的事,实现connectionMade方法时我们往服务器端发送一条消息

class TcpClient(Protocol):    SERVER_MAP = {}    def connectionMade(self):        addr = self.transport.addr  # 获取服务器端的连接信息        print("connected", self.transport.socket)        client_ip = addr[0]        TcpClient.SERVER_MAP[client_ip] = self        nowTime = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')        str = "你好服务器,我是客户端 " + nowTime        self.transport.write(str.encode("utf-8"))  # 向服务器发送信息    def connectionLost(self, reason):        addr = self.transport.addr  # 获取服务器端的连接信息        client_ip = addr[0]        if client_ip in TcpClient.SERVER_MAP:            del TcpClient.SERVER_MAP[client_ip]    def dataReceived(self, tcp_data):        addr = self.transport.addr  # 获取服务器端的连接信息        nowTime = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')        try:            msg = tcp_data.decode("utf-8")            print("Received msg", msg, "from Tcp Server", addr)            time.sleep(5)            str = "来自客户端的响应 " + nowTime            self.transport.write(str.encode("utf-8"))        except BaseException as e:            print("Comd Execute Error from", addr, "data:", tcp_data)            str = "客户端发生异常 " + nowTime            self.transport.write(str.encode("utf-8"))

·启动TCP客户端

因为在创建Factory类的时候和服务器端有些不一样,之前服务器端我们是通过Factory.forProtocol方法来实例化工厂对象的,而在客户端的时候我们是继承了Factory类的子类ClientFactory来实现的,所以我们需要重写buildProtocol方法来设置protocol实例

在TcpClientFactory类中重写buildProtocol方法:

class TcpClientFactory(ClientFactory):    def buildProtocol(self, addr):        print("Connected To Tcp Server", addr)        self.protocol = TcpClient()        return self.protocol

然后用以下代码来启动TCP客户端:

    host = "127.0.0.1"    port = 9527    reactor.connectTCP(host, port, TcpClientFactory())    reactor.run()

TCP客户端成功启动,并且连接上服务器端以后也没有报错

D:\MyWorkSpaces\tools\Anaconda3\envs\tf2\python.exe D:/MyWorkSpaces/projects/all/sample/python/twisted/client.pyStarting Connecting To Tcp Server ('127.0.0.1', 9527)Connected To Tcp Server IPv4Address(type='TCP', host='127.0.0.1', port=9527)connected Received msg 来自服务器的响应 2019-08-10 11:57:42 from Tcp Server ('127.0.0.1', 9527)

上述就是小编为大家分享的python中怎么利用twisted实现TCP通讯了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注行业资讯频道。

服务 方法 客户 服务器 客户端 端的 模块 信息 接口 注释 utf-8 实例 工厂 参数 地址 时候 端口 提示 通讯 成功 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网科技公司起名 上海互联网科技有限公司 平安科技 互联网 腾讯科技 互联网女皇 玖二柒互联网科技公司待遇 宁波青枫互联网科技有限公司 剑昆互联网络科技有限公司临桂 随着互联网科技发展 互联网科技公司实习生 互联网5g黑科技有哪些 链环科技传统企业怎么转型互联网 企晟互联网信息科技有限公司 恒生互联网科技业指数调整周期 互联网领先科技宣传片 互联网风格科技公司名称 互联网科技包装股份有限公司上市 宁波跨境商互联网科技有限公司 普陀区互联网教育科技管理办法 科技和互联网行业的特点 六子台科技互联网展会 南京欣网互联网络科技有限公司 科技互联网企业 合肥互联网科技公司 有木互联网科技 996高科技互联网公司 天津腾达互联网科技有限公司 中国互联网公司排名锤子科技 南通创西澳互联网科技有限公司 广州智享互联网科技 华人运通互联网科技公司
0