通过 TCP 套接字发送可变长度数据
我的应用程序需要通过 tcp 套接字发送/接收 xml 数据。无法包含任何类型的包含消息长度的固定长度标头。据我了解,通过 TCP 传输的数据可以这样到达接收方。
<信息
<信息- ge><内容
>hi
但不知何故,这种情况永远不会发生,这意味着通过一次 Send() 操作发送的数据(假设它短于或等于套接字缓冲区大小)始终通过一次 Receive() 操作完全读取。如果端点的套接字缓冲区足够大且从未超出,上述情况是否可能?
My application needs to send/receive xml data via a tcp socket. There is no way to include any kind of a fixed-length header containing message length. As far as I understand, data transmitted over tcp can come to the receipient like this.
<messa
ge><content
>hi</content>
</message>
But somehow this never happens meaning that data sent with one Send() operation (assuming it's shorter or equal than socket buffer size) is always read completely with one Receive() operation. Is the above scenario possible given that socket buffers of the endpoints are large enough and never exceeded?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
是的,这是可能的。
您确实不能假设一侧的 send() 操作中的缓冲区边界将与另一端相应的 recv() 所看到的缓冲区边界相匹配,即使大多数情况下似乎都是这种情况。
例如,如果您要发送大量数据,则接收操作系统可能会调用 TCP 流控制,而发送操作系统将只能发送缓冲区的一部分。或者底层网络可能有数据包大小限制,需要将数据分开,或者......
Yes, it is possible.
You really can not assume that the buffer boundaries in the send() operation on one side will match with the ones seen by the corresponding recv() at the other end, even if that appears to be the case most of the time.
For example, if you're sending a lot of data, it's possible that the receiving OS will invoke TCP flow control and the sending OS will only be able to send part of a buffer. Or maybe the underlying network has a packet size limitation that requires things to be split up, or ...
如果两者之间存在代理,则很容易发生这种情况。如果我们假设没有代理,客户端将收到与服务器发送的相同的数据包。如果您发送的数据块数小于链接的 TCP MSS,则客户端可能会收到一块数据。
但是,我不会依赖于此。通过查看结束标记 (
) 可以轻松判断 XML 消息的结束,因此从流中解析 XML 也很容易。
This can easily happen if there is a proxy between. If we assume there is no proxy, the client will receive the same packets as the server sends. If you send data in pieces less than TCP MSS of your link, the client will probably receive it in one piece.
However, I would not rely on this. It is easy to tell the end of an XML message by seeing the close tag (
</message>
), so it's easy to parse XML from a stream.您可以在消息中包含消息长度。您所要做的就是,当您发送 xml 消息时,在前 4 个字节中添加消息长度,然后添加 xml 消息。当您接收时,您将流的前 4 个字节作为消息长度,然后读取 xml 消息的每个字节
You can include the message length in your messages. All you have to do is, when you send the xml msg you prepend it with the msg length in the first 4 bytes and then the xml msg. When you receive you take the first 4 bytes of the stream as the msg length and then read each byte for the xml msg