Sockets TCP套接字读取不带帧或大小指示器的可变长度数据

Sockets TCP套接字读取不带帧或大小指示器的可变长度数据,sockets,tcp,Sockets,Tcp,我目前正在编写将数据传输到远程供应商的代码。传输将通过TCP套接字进行。我的问题是数据长度可变,没有框架或大小标记。发送数据没有问题,但我不确定处理返回数据的最佳方法 数据由不同的“消息”组成,但它们没有固定的大小。每条消息都有一个8或16字节的位图,指示此消息中包含哪些组件。有些组件是固定长度的,有些是可变的。对于整个消息的该部分,每个可变长度组件都有一个大小前缀 当我第一次打开套接字时,我会发送消息,每个消息都会收到响应。当我开始读取数据时,我应该在消息的开头。我需要解释位图以了解包含哪些消

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

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

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

一旦我读完了第一条信息,下一条就开始了。我关心的是,如果消息传输中途中断,如何恢复并正确找到下一条消息的开始

我将不得不模拟连接失败,我的代码需要在取消该消息之前自动重试设置的次数

我无法控制远程端的代码,无法将帧字节或大小前缀添加到消息中

欢迎使用最佳实践、设计模式或处理此问题的最佳方法。TCP流不能在消息中间“剪切”然后恢复

如果在传输中有足够短的中断,那么每一端的O/S将进行处理,并根据需要重新传输数据包,但这对最终用户应用程序是不可见的——就其而言,流是连续的


如果TCP连接完全断开,两端都必须重新打开连接。在这一点上,传输系统应该从一个新的消息边界重新开始。

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

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

一个非阻塞的read/recv调用将返回当前到达的值,您可以解析该值。如果在解析时,在到达消息末尾之前数据用完,请读取/接收更多数据并继续解析。冲洗重复一遍。请注意,如果另一条消息紧随其后,您可能会获得比特定消息所需的更多字节


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

如何知道消息之间的位图是8字节还是16字节?消息!=TCP数据包。供应商的设计规范规定,一条消息可以由多个TCP数据包传输。如果我收到一条部分消息,那么TCP连接将断开,我收到的下一个数据可能是前一条消息的延续或新消息的开始。@Jamscripth:如果连接断开,他们将不会继续从服务器发送数据包/消息,因为他们的一方也将断开。客户端必须打开一个新连接。在这一点上,根据协议的不同,您可以协商从您停止的地方开始,或者重新开始。大多数协议选择从新开始。我从来没有提到过数据包,我说的是“流”。我的全部观点是,TCP流不会“先删除后恢复”,至少不会涉及到用户空间套接字代码——内核隐藏了这一点。我认为,供应商丢失的信息,正是TCP套接字断开,然后我的代码重新连接时发生的事。当我重新连接时,第一个数据将是部分发送的任何消息的继续,还是将重试整个消息。@Jamscitch,您是正确的。TCP很容易预测。但情况并非如此。祝你好运