13

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

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

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

例子:

服务器发送...

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

客户端收到...“header1:message1header2:message2header3:message3”

我想收到三个单独的消息

header1:message1
header2:message2
header3:message3

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

4

3 回答 3

24

我猜你正在通过 TCP 连接交谈。

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

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

澄清:

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

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

于 2009-10-31T20:47:32.227 回答
1

您正在尝试做的是将您的数据分成“批次”。

例如,每当您从文件中读取“行”时,您就是在“批量”操作。什么定义了“线”?它是一个以“\n”结尾的字节序列。另一个例子是:你从一个文件中读取了 64KiB“块”。什么定义了“块”?你这样做了,因为你每次读取 65536 个字节。你想要一个可变长度的“块”吗?您只需在“块”前面加上它的大小,然后阅读“块”。“aiff”文件(其实现也是 MS Windows 的 .wav 和 .avi 文件)和“mov”文件是这样组织的。

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

  1. 记录分隔符
  2. 固定大小的记录
  3. 以它们的大小为前缀的记录。

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

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

于 2009-11-01T11:42:56.513 回答
0

只需在每条消息之后附加\n......就像

socket.send ("header1:message1\n")
socket.send ("header2:message2\n")
socket.send ("header3:message3\n")
于 2011-02-04T04:13:25.377 回答