【问题标题】:Reading socket buffer using asyncore使用异步读取套接字缓冲区
【发布时间】:2009-11-26 17:56:48
【问题描述】:

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

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

我已经设法让它发挥作用,但是,我不确定我这样做是否完全正确。因此,因此我的实际问题(要遵循的代码):

  1. 这是在 Python 中执行此操作的正确方法(即,真的这么简单吗)?
  2. 关于缓冲区/asyncore的任何提示/技巧/有用资源(参考文档除外)?

目前,数据的读取和缓冲如下:

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。第一个问题是主要问题(答案基于此),但任何其他想法/提示都值得赞赏。谢谢。

【问题讨论】:

  • 我很好奇你的代码中的 ByteUtils 在哪里,所以我用谷歌搜索了“python ByteUtils”......谷歌给了我这个线程 - 在它创建后 15 分钟!这令人印象深刻:)

标签: python sockets buffer asyncore


【解决方案1】:

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

而且,我强烈建议您使用 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()

【讨论】:

  • 我知道服务器通过所有以 CRLF 结尾的“行”发送,所以我确信在某个时间点缓冲区将被终止(除非服务器端出现问题,我猜这会立即将其发送到某种形式的缓冲区溢出中)。我读过 Twisted,但它还没有用于 Python 3 AFAIK,并且可能会为此过度。
  • 您仍然面临使用当前代码获得多行而不是一行的风险。
  • 我很少推荐 Twisted,但是,是的,它比古老的 asyncore 框架要好得多!
【解决方案2】:

它甚至更简单——查看asynchat 及其set_terminator 方法(以及该模块中的其他有用的花絮)。 Twisted 更加丰富和强大,但是,对于足够简单的任务,asyncore 和 asynchat(旨在顺利互操作)确实非常易于使用,正如您已经开始观察的那样。

【讨论】:

  • 我首先尝试了 asynchat,但遇到了一些我无法立即解决的问题(与缓冲区有关),所以我恢复为 asyncore。
  • +1 关于使用 asyncore/asynchat 而不是 Twisted 来完成这些简单的任务。
  • @Denis:我认为上面的扭曲示例非常简单而且直接,不是吗?
猜你喜欢
  • 2012-09-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-30
  • 1970-01-01
  • 2016-04-22
  • 2021-07-31
相关资源
最近更新 更多