Python/Twisted - TCP数据包分段?

6
在Twisted中实现dataReceived方法时,似乎没有任何关于数据包被分片的示例。在其他语言中,这是需要手动实现的,所以我想知道在Twisted中是否已经为您完成了这个过程?如果是这样,我需要在我的数据包前加上长度标头吗?还是我需要手动执行这个操作?如果需要手动执行,应该怎么做呢?
3个回答

6
在dataReceived方法中,您将得到一个长度不确定的字符串形式的数据,这意味着它可能是协议中的整个消息,也可能只是某个“客户端”发送给您的消息的一部分。您需要检查数据以查看它是否包含协议中的整个消息。
我目前正在使用Twisted在我的一个项目中实现协议,并决定使用struct模块来打包/解包我的数据。我正在实现的协议具有固定的头大小,因此在读取至少HEADER_SIZE字节之前,我不会构造任何消息。总消息大小在此标题数据部分中声明。
我想您实际上不需要将消息长度定义为协议的一部分,但这有助于。如果您没有定义,则必须有一个特殊的分隔符来确定消息何时开始/结束。就像FIX协议使用SOH字节来分隔字段一样。尽管它确实有一个必需的字段告诉您消息的长度(只是不告诉您消息中有多少个字段)。

2
在使用这种方法时要非常小心。相信客户端会告诉你它将发送多少数据,是引入缓冲区溢出或类似攻击的经典方式。 - Jesse Weigert
2
Jesse,我认为你没有正确理解这个答案。首先,Twisted是用Python编写的,因此你几乎不可能遇到缓冲区溢出的情况。其次,分隔输入比长度前缀输入更容易导致缓冲区溢出;例如,请参阅http://cr.yp.to/proto/netstrings.txt的安全部分或任何一本关于C网络编程的书籍。这里的想法并不是你“信任”客户端告诉你它将发送多少数据 - 而是客户端告诉你有多少字节(发送的任意数量)构成一个消息。 - Glyph

6

在处理TCP时,您应该真正忘记所有“数据包”的概念。TCP是一种流协议--您将数据流入,数据从另一侧流出。一旦数据被发送,它可以以任何数量或任何块的形式到达,只要所有数据以正确的顺序到达即可。您将需要像其他语言一样手动进行分隔,使用长度字段、消息类型字段、特殊分隔符字符等。


希望我能在这个问题上再投几票,twisted协议类中的"dataReceived"方法在每次接收到数据包时都会被触发,您需要确保所有数据都已接收完毕,然后才能移动并写入协议接收到的数据。 - snarkyname77

2

你也可以使用LineReceiver协议


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