2009-10-31 23 views
9

我已经写了一个服务器在Python中,旨在以“头:消息”的形式发送数据到客户端如何刷新Python套接字?

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

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

例子:

服务器发送...

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

客户端收到...... “头1:message1header2:message2header3:MESSAGE3”

我愿意接受三个个人信息

header1:message1 
header2:message2 
header3:message3 

我需要一种方法来刷新eac后h send

+0

完全重复:http://stackoverflow.com/questions/1097974/how-to-flush-a-socket-in-python – ChristopheD 2009-10-31 20:46:49

+4

*不是重复:*标题是*字面*重复,但问题实际上*功能*不同。 OP需要一个答案,就像下面的@ebo一样。 – 2009-10-31 20:50:51

+1

糟糕,这似乎是正确的。下次尝试会慢一点;-) – ChristopheD 2009-10-31 20:58:59

回答

19

我猜你正在通过TCP连接进行通话。

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

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

澄清:

冲洗发送缓冲区通常会产生新的软件包,就像你期望的那样。如果您的客户端读取这些软件包的速度足够快,则可能每次读取一条消息

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

+0

+1:我会为了edumacations的缘故添加,即使@Jah是刷新套接字,他的客户仍然会收到完全相同的消息 - 刷新是关于以延迟减少名义清除缓冲区,以及*不*划分消息。 – 2009-10-31 21:00:28

+0

给出了一个场景来说明这可能会出错。 thx @ stu – ebo 2009-10-31 21:31:46

+0

+1:TCP是一个流。 TCP数据的时间通过互联网路由和TCP协议被特别消除。数据必须缓冲; “冲洗”实际上并不意味着太多。所有这一切意味着您的数据已经超出了您的应用程序的缓冲区并进入了TCP协议缓冲区。 – 2009-10-31 23:23:36

0

你正在试图做的是将你的数据分成“批”。

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

这三种方法是组织字节流,无论媒体最根本的方法:

  1. 记录分隔
  2. 固定大小记录
  3. 记录及其大小前缀。

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

选择一种方法,并在作者和读者中实现它。如果你还记录你的选择,你刚刚定义了你的第一个协议。

3

只是追加\ n每封邮件...... 像

socket.send后( “头1:MESSAGE1 \ n”)

socket.send( “标题2:消息2 \ n”)

socket.send(“header3:message3 \ n”)

+1

这对我有用! – 2014-06-30 01:10:02

+0

“\ n”不保证邮件是分开的。 – crey4fun 2017-04-09 22:04:01