如何刷新 Python 套接字?
我用Python编写了一个服务器,旨在以“标题:消息”的形式将数据发送到客户端,
我希望能够单独发送每条消息,以便客户端只需执行最少的工作即可读取“标头”和“消息”
不幸的是,我不知道如何正确刷新Python套接字,因此当我快速连续执行多个发送时,消息会集中在套接字缓冲区中并作为一个大块发送。
示例:
服务器发送...
socket.send ("header1:message1")
socket.send ("header2:message2")
socket.send ("header3:message3")
客户端接收... “header1:message1header2:message2header3:message3”
我想收到三条单独的消息,
header1:message1
header2:message2
header3:message3
我需要一种在每次发送后刷新的方法
I've written a server in Python that is meant to send data to the client in the form "Header:Message"
I would like to be able to have each message sent individually so that the client will need to perform minimal work in order to read the "header" and the "message"
Unfortunately, I can't figure out how to properly flush a python socket so when I have multiple sends execute in quick succession the messages get lumped together in the socket buffer and sent as one big chunk.
Example:
Server sends...
socket.send ("header1:message1")
socket.send ("header2:message2")
socket.send ("header3:message3")
Client receives...
"header1:message1header2:message2header3:message3"
I'd like to receive three individual messages
header1:message1
header2:message2
header3:message3
I need a way to flush after each send
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我猜你正在通过 TCP 连接进行交谈。
你的方法有缺陷。 TCP 流被定义为字节流。您始终必须使用某种分隔符,并且可能不依赖网络堆栈来分隔消息。
如果您确实需要基于数据报的服务,请切换到 UDP。在这种情况下,您需要自己处理重传。
澄清一下:
正如您所期望的那样,刷新发送缓冲区通常会创建新的包。如果您的客户端足够快地读取这些包,您每次读取可能会收到一条消息。
现在想象一下您通过卫星链路进行通信。由于高带宽和延迟,卫星之前的最后一个路由器会等待很短的时间,直到缓冲区中有足够的数据并立即发送所有数据包。您的客户端现在将立即接收所有数据包,并将所有数据立即放入接收缓冲区中。于是你们的分离又消失了。
I guess you are talking over a TCP connection.
Your approach is flawed. A TCP stream is defined as a stream of bytes. You always have to use some sort of separator and may not rely on the network stack to separate your messages.
If you really need datagram based services switch to UDP. You'll need to handle retransmission yourself in that case.
To clarify:
Flushing the send buffer usually creates new packages, just as you expect. If your client reads these packages fast enough you may get one message per read.
Now imagine you communicate over a satellite link. Because of high bandwidth and latency, the last router before the sat waits a short time until enough data is in the buffer and sends all your packets at once. Your client will now receive all packets without delay and will put all the data in the receive buffer at once. So your separation is gone again.
您想要做的是将数据分成“批次”。
例如,每当您从文件中读取“行”时,您都是在“批量”操作。 “线”的定义是什么?它是一个以“\n”结尾的字节序列。另一个例子是:您从文件中读取了 64KiB“块”。什么定义了“块”?确实如此,因为每次读取 65536 字节。你想要一个可变长度的“块”吗?您只需在“块”前面加上其大小,然后读取“块”即可。 “aiff”文件(其实现也是 MS Windows 的 .wav 和 .avi 文件)和“mov”文件的组织方式类似。
这三种方法是组织字节流的最基本方法,无论使用何种介质:
它们可以混合和/或修改。例如,您可以拥有“变量记录分隔符”,如 XML 读取器:从第一个 '<' 读取字节直到第一个“>”,在第一个“<”后添加斜杠并将其称为记录结束,读取流直到记录结束。这只是一个粗略的描述。
选择一种方法,并在编写器和读取器中实现它。如果您还记录了您的选择,则您刚刚定义了第一个协议。
What you are trying to do, is split your data into "batches".
For example, you are operating on "batches" whenever you read "lines" off a file. What defines a "line"? It's a sequence of bytes terminated by '\n'. Another example is: you read 64KiB "chunks" off a file. What defines a "chunk"? You do, since you read 65536 bytes every time. You want a variable length "chunk"? You just prefix your "chunk" with its size, then read the "chunk". "aiff" files (whose implementations are also the .wav and .avi files of MS Windows) and "mov" files are organized like that.
These three methods are the most fundamental methods to organize a stream of bytes, whatever the medium:
They can be mixed and/or modified. For example, you could have "variable record separators", like an XML reader: read bytes from first '<' until first '>', add a slash after first '<' and call it end-of-record, read stream until end-of-record. That's just a crude description.
Choose a method, and implement it in both the writer and reader. If you also document your choices, you've just defined your first protocol.
我在“刷新”UDP 套接字的缓冲区时遇到了同样的问题,这是我的解决方案:
I had the same problem to "flush" the buffer of a UDP socket, and here is my solution:
只需在每条消息后附加
\n
...喜欢
just append
\n
after every message...like