2010-09-07 130 views
3

我的应用程序需要通过tcp套接字发送/接收xml数据。无法包含任何类型的包含消息长度的固定长度头。据我了解,通过tcp传输的数据可以像这样来到收件人。通过TCP套接字发送可变长度数据

  1. < MESSA

  2. GE > <内容

  3. >喜< /内容>

  4. < /消息>

但是不知何故,这种情况永远不会发生,这意味着使用一个Send()操作发送的数据(假设它比套接字缓冲区的大小更短或等于)总是通过一个Receive()操作完全读取。考虑到端点的套接字缓冲区足够大并且从不超过,上述情况是否可能?

回答

1

这可以很容易地发生,如果之间有一个代理。如果我们假设没有代理,则客户端将收到与服务器发送的数据包相同的数据包。如果您发送的数据量小于链接的TCP MSS数量,则客户端可能会一次性收到它。

但是,我不会依赖这个。通过查看关闭标记(</message>)很容易判断XML消息的结束,因此从流中解析XML很容易。

+0

可以以任何想要的方式将分割数据代理为块?数据真的很小,10KB或更少.. – 2010-09-07 17:39:35

+1

这不仅仅是一个代理问题,它可以随时发生。 TCP只是一个流,不是面向数据包的。例如如果网络拥塞,你发送的东西真的很快,操作系统网络缓冲区已满。如果你碰巧用一个Receive获得所有数据,那么你很幸运 - 不应该依赖它。 – nos 2010-09-07 17:42:09

+0

@ user375487是的,代理可以以任何想要的方式拆分。另外,10K已经超过了TCP MSS,所以如果网络足够慢,接收器可能会收到更小的片断。 – unbeli 2010-09-07 17:58:04

4

是的,这是可能的。

你真的不能假定一方的send()操作中的缓冲区边界将与另一端的相应recv()所看到的缓冲区边界相匹配,即使这看起来像是大多数情况下时间。

例如,如果您发送大量数据,接收操作系统可能会调用TCP流量控制,并且发送操作系统只能发送部分缓冲区。或者,也许底层网络有一个数据包大小限制,需要分割的东西,或...

+0

数据真的很小。即使数据为10 KB或更少,这些事情是否也会发生? – 2010-09-07 17:40:59

+0

是的,它可以。此外,如果您发送的邮件超过1条时间相对接近,您的接收可能会同时读取它们,或者它可能会读取下一条信息的前一半。如果在正确的时间出现虚假的网络问题,“及时接近”可能需要几分钟时间。 – nos 2010-09-07 17:51:50

0

您可以在消息中包含消息长度。所有你需要做的是,当你发送xml msg时,你在前4个字节中加上msg长度,然后是xml msg。当你收到你的流的前4个字节作为味精长度,然后读取每个字节的xml msg

+0

我假设,因为这个问题。 – 2010-09-07 17:45:24

+0

我的不好。因为我虽然说过“没有办法包含任何类型的包含消息长度的固定长度标题” – Cratylus 2010-09-07 17:59:32

+0

是的,这就是我所说的。只有xml数据必须传输,这是我无法改变的要求。你不能用任何你想要的数据预先加载http请求或电子邮件,除非你不想让它们解析,对吗?这是一个类似的情况。 – 2010-09-07 18:35:37

相关问题