You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python3.8+Twisted22.10.0连接FreeSWITCH遇字节类型TypeError

问题

使用Python3.8和Twisted22.10.0,通过Reactor与事件套接字连接FreeSWITCH并处理事件,已成功建立TCP连接,但运行Reactor线程后出现以下错误:

Unhandled Error
Traceback (most recent call last):
File "/home/.local/lib/python3.8/site-packages/twisted/python/log.py", line
96, in callWithLogger
return callWithContext({"system": lp}, func, *args, **kw)
File "/home/.local/lib/python3.8/site-packages/twisted/python/log.py", line
80, in callWithContext
return context.call({ILogContext: newCtx}, func, *args, **kw)
File "/home/.local/lib/python3.8/site-packages/twisted/python/context.py",
line 117, in callWithContext
return self.currentContext().callWithContext(ctx, func, *args, **kw)
File "/home/.local/lib/python3.8/site-packages/twisted/python/context.py",
line 82, in callWithContext
return func(*args, **kw)
--- ---
File "/home/.local/lib/python3.8/site-packages/twisted/internet/posixbase.py",
line 487, in _doReadOrWrite
why = selectable.doRead()
File "/home/.local/lib/python3.8/site-packages/twisted/internet/tcp.py", line
249, in doRead
return self._dataReceived(data)
File "/home/.local/lib/python3.8/site-packages/twisted/internet/tcp.py", line
256, in _dataReceived
rval = self.protocol.dataReceived(data)
File "/home/.local/lib/python3.8/site-packages/twisted/protocols/basic.py",
line 542, in dataReceived
line, self._buffer = self._buffer.split(self.delimiter, 1)
builtins.TypeError: a bytes-like object is required, not 'str'

代码片段:

from twisted.internet import protocol, reactor
factory = MyFactory()
reactor.connectTCP('127.0.0.1', 8021, factory)
reactor.run(installSignalHandlers=0)


class MyFactory(protocol.ReconnectingClientFactory):
    def __init__(self):
        self.password = '----'
        MyFactory.stopDeferred = defer.Deferred()

    def buildProtocol():
        some code here to build protocol
        return protocol

排查发现basic.py中self._buffer和self.delimiter均为字节类型,不想修改该文件,求解决方法。

解决方案

这个错误的核心是字符串与字节类型不匹配,Twisted的TCP传输默认传递字节数据,但协议处理逻辑中混入了字符串操作,或使用了错误的协议模式,解决方法如下:

  • 使用字节版基础协议类
    若使用LineReceiver这类基础协议,Python3下Twisted默认处理字节数据,需确保继承的是twisted.protocols.basic.LineReceiver,且将所有分隔符设置为字节类型,比如把delimiter = '\n'改为delimiter = b'\n'。

  • 统一数据类型处理
    所有与传输相关的操作必须保持字节一致:发送数据时用self.transport.write(b"your_command"),不能直接传字符串;处理dataReceived传入的字节数据时,如需转文本操作,先解码为字符串,处理完成后再编码回字节发送。

  • 修正buildProtocol方法
    原方法缺少必要参数,且返回的协议实例需保证属性类型正确,示例修正如下:

    from twisted.internet import protocol, reactor, defer
    
    class MyProtocol(protocol.Protocol):
        def connectionMade(self):
            # 发送认证及订阅事件命令,均用字节类型
            self.transport.write(b"auth your_password_here\n")
            self.transport.write(b"event plain ALL\n")
    
        def dataReceived(self, data):
            # 字节转字符串处理
            response = data.decode('utf-8')
            # 后续业务逻辑
            print(response)
    
    class MyFactory(protocol.ReconnectingClientFactory):
        def __init__(self):
            self.password = b'----'  # 密码改为字节类型
            self.stopDeferred = defer.Deferred()
    
        def buildProtocol(self, addr):  # 补全self和addr参数
            self.resetDelay()
            return MyProtocol()
    
    factory = MyFactory()
    reactor.connectTCP('127.0.0.1', 8021, factory)
    reactor.run(installSignalHandlers=0)
    
  • 排查混合操作
    检查协议代码中是否存在字符串与字节直接拼接、赋值的情况,统一转换为同一类型后再操作。

内容的提问来源于stack exchange,提问作者Eranki

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 17:09:55