你如何刷新Python套接字?

时间:2009-10-31 20:38:59

标签: python sockets flush

我用Python编写了一个服务器,用于以“Header:Message”形式向客户端发送数据

我希望能够单独发送每条消息,以便客户端需要执行最少的工作才能阅读“标题”和“消息”

不幸的是,我无法弄清楚如何正确刷新python套接字,所以当我有多个发送快速连续执行时,消息会在套接字缓冲区中集中在一起并作为一个大块发送。

示例:

服务器发送...

socket.send ("header1:message1")
socket.send ("header2:message2")
socket.send ("header3:message3")

客户收到...... “头1:message1header2:message2header3:消息3”

我想收到三条消息

header1:message1
header2:message2
header3:message3

我需要一种方法在每次发送后刷新

3 个答案:

答案 0 :(得分:21)

我猜你是在谈论TCP连接。

你的方法存在缺陷。 TCP流被定义为字节流。您总是必须使用某种分隔符,并且可能不依赖于网络堆栈来分隔您的消息。

如果您确实需要基于数据报的服务切换到UDP。在这种情况下,你需要自己处理重传。

澄清:

刷新发送缓冲区通常会创建新的包,就像您期望的那样。如果您的客户端足够快地读取这些包,则每次读取可能会收到一条消息。

现在假设您通过卫星链接进行通信。由于高带宽和延迟,sat之前的最后一个路由器等待很短的时间,直到有足够的数据进入缓冲区并立即发送所有数据包。您的客户端现在将立即接收所有数据包,并将所有数据立即放入接收缓冲区。所以你的分离再次消失。

答案 1 :(得分:3)

在每条消息后添加\n ... 喜欢

socket.send ("header1:message1\n")
socket.send ("header2:message2\n")
socket.send ("header3:message3\n")

答案 2 :(得分:1)

您要做的是将数据拆分为“批次”。

例如,只要您从文件中读取“行”,就会在“批处理”上进行操作。是什么定义了“线”?它是由'\ n'终止的字节序列。另一个例子是:你从文件中读取64KiB“块”。是什么定义了“块”?你这样做,因为你每次都读取65536个字节。你想要一个可变长度的“块”?你只需在其“大块”前加上它的大小,然后读取“块”。 “aiff”文件(其实现也是MS Windows的.wav和.avi文件)和“mov”文件的组织方式如此。

这三种方法是组织字节流的最基本方法,无论介质如何:

  1. 记录分隔符
  2. 固定大小的记录
  3. 以其大小为前缀的记录。
  4. 可以混合和/或修改它们。例如,您可以使用“变量记录分隔符”,如XML阅读器:从第一个'<'读取字节直到第一个'>',在第一个'<'之后添加一个斜杠并将其称为记录结束,读取流直到记录结束。这只是一个粗略的描述。

    选择一种方法,并在编写器和阅读器中实现它。如果您还记录了您的选择,那么您刚刚定义了第一个协议。