Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何使用Twisted中接收的数据?_Python_Twisted - Fatal编程技术网

Python 如何使用Twisted中接收的数据?

Python 如何使用Twisted中接收的数据?,python,twisted,Python,Twisted,我用Twisted实现了一个服务器程序。我正在使用basic.lineReceiver方法dataReceived从多个客户端接收数据。此外,我还使用protocol.ServerFactory跟踪连接的客户端。服务器向每个连接的客户端发送一些命令。根据服务器从每个客户端获得的响应,它(服务器)应该执行一些任务。因此,我想到的最佳解决方案是为接收到的消息创建一个缓冲区作为python列表,每次服务器端的函数想要知道来自客户端的响应时,它们都会访问缓冲区列表(该客户端的)的最后一个元素。 事实证明

我用Twisted实现了一个服务器程序。我正在使用
basic.lineReceiver
方法
dataReceived
从多个客户端接收数据。此外,我还使用
protocol.ServerFactory
跟踪连接的客户端。服务器向每个连接的客户端发送一些命令。根据服务器从每个客户端获得的响应,它(服务器)应该执行一些任务。因此,我想到的最佳解决方案是为接收到的消息创建一个缓冲区作为python列表,每次服务器端的函数想要知道来自客户端的响应时,它们都会访问缓冲区列表(该客户端的)的最后一个元素。 事实证明,这种方法是不可靠的。第一个问题是,由于使用了TCP流,有时消息会合并(我可以使用分隔符)。其次,接收到的消息有时不在其适当的顺序中。第三,网络通信似乎太慢,因为当服务器最初尝试访问缓冲列表的最后一个元素时,列表为空(这表明缓冲区上的最后一条消息可能不是对最后发送的命令的响应)。 您能告诉我在上述问题中使用
dataReceived
或其等价物的最佳方案是什么吗?先谢谢你

编辑1:答案-虽然我接受@Jean-Paul Calderone的答案,因为我确实从中学习到了,但我想补充一点,在我自己对Twisted文档的研究中,我了解到为了避免服务器通信延迟,应该在dataReceived()或lineReceived()的末尾使用
return
功能,这解决了我的部分问题。其余的都在回答中解释了

我用Twisted实现了一个服务器程序。我使用basic.lineReceiver和dataReceived方法从多个客户端接收数据

这是一个错误——不幸的是,在Twisted的许多协议实现中错误地使用继承作为建立越来越复杂行为的机制,这是一个常见的错误。使用
twisted.protocols.basic.LineReceiver
时,
dataReceived
回调不适合您
LineReceiver.dataReceived
LineReceiver
的实现细节。您的回调是
LineReceiver.lineReceived
LineReceiver.dataReceived
看起来可能适合您—它不是以下划线或任何东西开头—但它不是
dataReceived
LineReceiver
从其传输接收信息的方式。它是
IProtocol
的公共方法之一,IProtocol是传输和协议之间的接口,解释通过该传输接收的数据。是的,我刚才说的是“公共方法”。问题是它是为了其他人的利益而公开的。这是令人困惑的,可能没有传达得那么好。毫无疑问,这就是为什么它是一个好消息

事实证明,这种方法是不可靠的。第一个问题是,由于使用了TCP流,有时消息会合并(我可以使用分隔符)

使用
dataReceived
就是发生这种情况的原因
LineReceiver
已经为您实现了基于分隔符的解析。这就是为什么它被称为“行”接收器-它接收由分隔符分隔的行。如果覆盖
lineReceived
而不是
dataReceived
,则无论TCP如何将内容拆分或粉碎,都会调用接收到的每一行

其次,接收到的消息有时不在其适当的顺序中

TCP是一种可靠、有序、面向流的传输。“有序”表示字节的到达顺序与发送顺序相同。换句话说,当你
写(“x”);写入(“y”)
保证接收器在收到“y”之前会收到“x”(在对
recv()
的同一次调用中,他们可能会收到“x”和“y”,但如果收到,数据肯定是“xy”而不是“yx”;或者他们可能会在对
recv()
的两次调用中收到两个字节,如果收到,则是第一个
recv())
肯定是“x”,第二个肯定是“y”,而不是相反)

如果字节的到达顺序与您发送的顺序不同,则可能有另一个bug使其看起来像是在发生这种情况,但实际上并非如此。您的平台的TCP堆栈很可能几乎没有bug,特别是它可能没有TCP数据重新排序bug。同样,这一扭曲区域经过了非常好的测试,可能工作正常。这会在您的应用程序代码中留下一个bug,或者对您的观察结果产生误解。也许您的代码并不总是将数据附加到列表中,或者数据没有按照您期望的顺序发送

另一种可能性是,您正在讨论数据通过多个单独的TCP连接到达的顺序。TCP仅在单个连接上订购。如果您有两个连接,则很少(如果有的话)保证数据通过它们到达的顺序

第三,网络通信似乎太慢,因为当服务器最初尝试访问缓冲列表的最后一个元素时,列表为空(这表明缓冲区上的最后一条消息可能不是对最后发送的命令的响应)

什么定义“太慢”?网络和网络一样快。如果这对你来说还不够快,那就找一块更肥的铜片。听起来您在这里真正的意思是,您的服务器有时希望数据在实际到达之前到达。但这并不意味着网络速度太慢,而是意味着服务器没有正确的事件驱动。如果您正在检查缓冲区,但没有找到您需要的信息