解析来自 TCP 流的数据包



我经常编写简单的python TCP服务器,它在解析以长度为前缀的数据包后响应请求。假设套接字已设置,这通常看起来很像这样:

def tcp_server_loop():
    msg = ''
    msg_len = 0
    while True:
        msg += sock.recv(4096)
        if len(msg) >= 4 and msg_len == 0:
            msg_len, = struct.unpack_from("!I", msg)
        if len(msg) >= msg_len:
            protocol.parse_packet(msg[:msg_len])
            msg = msg[msg_len:]
            msg_len = 0

这很有效,并且对我有很多次很好的帮助,但我总是对附加在 msg += sock.recv(4096) 中的字符串感到恼火。对于小数据包来说,这还不错,因为为这些小字符串分配新存储的开销还不错。但是对于大型数据包(MB),在Python的字符串实现中,大量的复制在幕后进行。

在 C 或一些类似语言中,环形缓冲区是明显的数据结构,大小适合您期望的最大数据包。但是,我还没有找到类似的Python实现。我想知道是否有人可以改进我上面的代码。您如何实现这些类型的服务器?

首先是一个快速建议:为了清楚起见,您可能希望将packet_size重命名为msg_len。 您尝试从 TCP 流中解析出的是应用程序级协议消息,而不是 TCP 段(也称为 TCP 数据包)。

但是为了解决您的问题:更有效的方法是,当您收到消息标头时,分配第二个固定bytearray大小的缓冲区,长度为msg_len。 使用此选项来存储您随后读入的数据。

相关内容

  • 没有找到相关文章

最新更新