TCP套接字读取可变长度数据没有框架或大小指示器

时间:2012-10-02 14:00:26

标签: sockets tcp

我目前正在编写代码以将数据传输到远程供应商。传输将通过TCP套接字进行。我遇到的问题是数据长度可变,没有框架或尺寸标记。发送数据没问题,但我不确定处理返回数据的最佳方法。

数据由不同的“消息”组成,但它们没有固定的大小。每条消息都有一个8或16字节的位图,指示此消息中包含哪些组件。有些组件是固定长度的,有些是可变的。每个可变长度组件都具有整个消息的该部分的大小前缀。

当我第一次打开套接字时,我将发送消息,每个消息都会收到响应。当我开始阅读数据时,我应该在消息的开头。我需要解释位图以了解包含哪些消息字段。当数据到达时,我将必须验证位图指示的每个字段是否存在且具有正确的大小。

一旦我读完了所有第一条消息,就会开始下一条消息。我担心的是,如果传输在消息中途被切断,我该如何恢复并正确查找下一条消息?

我必须模拟连接失败,我的代码需要在取消该消息之前自动重试一定次数。

我无法控制远端的代码,也无法在消息中添加成帧字节或大小前缀。

最佳实践,设计模式或最佳处理方式的想法都受到欢迎。

3 个答案:

答案 0 :(得分:1)

TCP流不能在消息中“切断”然后恢复。

如果传输中断足够短,那么每端的O / S都会处理,并且必要时会重新传输数据包,但对最终用户应用程序来说是不可见的 - 只要它关注的是流是连续的。 / p>

如果TCP连接完全丢失,则两端都必须重新打开连接。此时,传输系统应该在新的消息边界重新开始。

答案 1 :(得分:1)

从用户的角度来看,TCP是数据的,就像您可能通过串行端口接收一样。没有数据包也没有标记。

非阻塞的read / recv调用将返回您当前到达的内容,您可以解析该内容。如果在解析时,在到达消息末尾之前用完数据,请读取/重新获取更多数据并继续解析。冲洗。重复。请注意,如果特定消息需要跟随特定消息,则可以获得更多字节。

TCP流不会丢失或重新排序字节。除非连接中断或发件人有错误(例如,只能写入/发送部分,然后从未尝试写/发送其余部分),否则消息不会被截断。您无法继续损坏的TCP流。你只能开一个新的并重新开始。

答案 2 :(得分:0)

对于这样的事情,你可能会更容易使用网络框架(如netty),或者完全不同的IO机制,比如Iteratee IO和Play 2.0。