Twisted Python: 最大数据包大小?刷新套接字?

3
我正在实现一个基于Twisted的客户端-服务器解决方案,客户端使用Android手机等设备。由于Andoird模拟器无法处理大于1500字节的TCP数据包(或更少?),因此我需要能够在服务器端对数据包进行分块。如果在每个“transport.write”后不刷新套接字,Twisted会缓冲输出数据,因此分块将变得无用,除非有一些手动或自动刷新/最大数据包大小函数。如何在Twisted中实现这一点?
我熟悉“reactor.doSelect(1)”函数,但由于我正在使用EPoll反应堆(出于可伸缩性和性能考虑),因此我不能使用doSelect。是否可能在Twisted中更改某些连接的maxPacketValue?
希望有人能为我指点迷津...

1
这太奇怪了,问题竟然神奇地自己解决了...之前未能传输到客户端的大型测试数据包现在又可以正常工作了,我不知道为什么...暂时来说,案子就这样结束了! - Dirk
1
你永远不应该调用doSelect方法。它并不会执行你想要的操作。 - Jean-Paul Calderone
问题并没有神奇地自行解决。你的网络条件发生了变化,所以它现在可以工作...但它会再次改变,并再次出现故障。请查看我的答案,它应该解释如何真正修复您的代码。 - Glyph
2个回答

2
TCP数据包会被操作系统自动分块,应用程序只能在刷新时给出提示。除此之外,应用程序可以直接读写流。
两个通信节点的操作系统将基于链路的MTU自动配置最大数据包大小,使用路径MTU发现。确保不要阻止ICMP数据包以使其正常工作。
由于错误的MTU极不可能是问题的原因(而且MTU通常设置为1500或更少),您应该重新诊断您的问题,例如使用wireshark这样的数据包跟踪器。

2
TCP是面向流的协议,而不是面向数据包的协议。当您调用 transport.write 时,该数据将附加到TCP流中,并可以分为任意数量的数据包发送出去;它可能会被拆分,或者与下一个或上一个 write 调用粘合在一起。这是关于Twisted的一个相当常见的问题,但是每个提问者都以稍微不同的方式提出。
您应该使用像AMP这样的协议构建工具包,或者更基础的LineReceiver,以定界协议中的消息,而不是依赖于数据包边界的随机性。

我想要一个LineSender... - John Carlson
LineReceiver 类有一个 sendLine 方法:https://docs.twistedmatrix.com/en/stable/api/twisted.protocols.basic.LineReceiver.html#sendLine - Glyph

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接