我是Python的新手(虽然我已经用Java编程多年了),我正在开发一个简单的基于套接字的网络应用程序(只是为了好玩)。我的想法是我的代码连接到远程TCP端点,然后侦听从服务器推送到客户端的任何数据,并对此执行一些解析。

从服务器推送的数据 - > client是UTF-8编码的文本,每行由 CRLF \ x0D \ x0A )分隔。您可能已经猜到:想法是客户端连接到服务器(直到被用户取消),然后在它们进入时读取和解析这些行。

我已经设法让这个工作,然而,我不确定我这样做是否正确。因此,我的实际问题(代码要遵循):

  1. 这是用Python做的正确方法吗(即它真的很简单吗?)
  2. 有关buffers / asyncore 的任何提示/技巧/有用资源(参考文档除外)?
  3. 目前,正在按如下方式读取和缓冲数据:

    def handle_read(self):
        self.ibuffer = b""
    
        while True:
            self.ibuffer += self.recv(self.buffer_size)
            if ByteUtils.ends_with_crlf(self.ibuffer):
                self.logger.debug("Got full line including CRLF")
                break
            else:
                self.logger.debug("Buffer not full yet (%s)", self.ibuffer)
    
        self.logger.debug("Filled up the buffer with line")
        print(str(self.ibuffer, encoding="UTF-8"))
    

    ByteUtils.ends_with_crlf 函数只是检查缓冲区的最后两个字节是否为 \ x0D \ x0A 。第一个问题是主要问题(答案是基于此),但任何其他想法/提示表示赞赏。感谢。

有帮助吗?

解决方案

TCP是一个流,您不能保证您的缓冲区不会包含一条消息的结尾和下一条消息的开头。 因此,在缓冲区末尾检查\ n \ r \ n将无法在所有情况下按预期工作。您必须检查流中的每个字节。

而且,我强烈建议您使用Twisted而不是asyncore。 像这样的东西(从内存中,可能无法开箱即用):

from twisted.internet import reactor, protocol
from twisted.protocols.basic import LineReceiver


class MyHandler(LineReceiver):

    def lineReceived(self, line):
        print "Got line:", line


f = protocol.ClientFactory()
f.protocol = MyHandler
reactor.connectTCP("127.0.0.1", 4711, f)
reactor.run()

其他提示

它更简单 - 看看 asynchat 及其 set_terminator 方法(以及该模块中的其他有用的花絮)。 Twisted 的数量级更丰富,更强大,但是,对于足够简单的任务,asyncore和asynchat(它们是设计为平滑互操作,确实非常简单,因为你已经开始观察了。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top