扭曲的Python: 最大数据包大小?刷新套接字?
我正在实现一个基于Twisted的客户端-服务器解决方案,服务器端用Twisted,客户端用安卓手机。因为安卓模拟器不支持超过1500字节的TCP数据包(或者更小?),所以我需要在服务器端将数据包分块。如果在每次“transport.write”之后不刷新socket,Twisted会把要发送的数据缓存起来,这样分块就没用了,因为没有手动或自动刷新/最大数据包大小的功能。我该如何在Twisted中做到这一点?
我对“reactor.doSelect(1)”这个函数有些了解,但因为我使用的是EPoll反应器(为了扩展性和性能),所以不能使用doSelect。有没有办法在Twisted中为某些连接更改最大数据包值?
希望有人能给我指条明路……
2 个回答
TCP是一种面向流的协议,而不是面向数据包的协议。当你调用transport.write
时,数据会被添加到TCP流中,可能会以任意数量的数据包发送出去;这意味着数据可能会被拆分,也可能会和前一个或下一个write
调用的数据合并在一起。这是一个关于Twisted的常见问题,很多人问这个问题,但每个人问的方式都有点不同。
你应该使用像AMP这样的协议构建工具,或者更简单的LineReceiver,来划分你协议中的消息,而不是依赖于数据包边界的随机性。
TCP数据包会被操作系统自动分成小块,应用程序只能给出一些提示,告诉系统什么时候该发送这些数据。除此之外,应用程序只需要在数据流中进行读写就可以了。
两个进行通信的设备的操作系统会根据网络链接的最大传输单元(MTU)自动调整数据包的最大大小,这个过程叫做路径MTU发现。要确保你没有阻止ICMP数据包,这样才能让这个过程正常工作。
因为出现错误的MTU的可能性非常小(而且通常设置的MTU值为1500或更小),所以你应该重新检查一下你的问题,比如使用一个叫做wireshark的数据包分析工具。