解析TCP数据包

时间:2013-01-07 15:52:14

标签: java parsing tcp packet

我在从套接字解析TCP数据包时遇到了一些麻烦......

在我的协议中,我的消息是这样的:

  

'A''B''C''D''E' ......... 0x2300

'p'''''''''''''''''''''开始消息模式

0x2300 - >两个字节结束消息

但是由于Nagle's algorithm,有时我的消息会连接起来:

'A''B''C''D''E' ......... 0x2300'A''B''C''D''E” ....... ..0x2300'A''B''C''D''E” ......... 0x2300

我已经尝试setNoDelay()为真,但问题仍然存在。

我有一个字节[]的消息。

我如何分割我的消息以便单独解析?

PS:现在我能收到第一条消息但其他消息丢失了......

3 个答案:

答案 0 :(得分:3)

只需循环访问您收到的数据并检查结束标记。找到后,为下一个包设置起始索引并继续搜索。像这样:

int packageStart = 0;
for(int i = 0; i < data.length - 1; i++) {
  if(data[i] == 0x23 && data[i + 1] == 0x00) {
      // Found end of package
      i++;
      processPackage(data, packageStart, i);
      packageStart = i;
  }
  // At this point: from packageStart till data.length are unprocessed bytes...

如上所述,可能会有一些遗留数据(如果data没有以结束标记结束)。您可能希望保留它,因此您可以将其添加到下一批接收的数据中。从而防止因切碎的TCP / IP包而导致的数据丢失。

答案 1 :(得分:2)

您必须将其视为解析连续的字节流。您的代码需要识别消息的开头和结尾。

由于数据包的发送方式,您可能拥有完整的消息,多条消息,部分消息等。您的代码需要识别消息何时开始并继续阅读,直到找到消息结束或在某些情况下,当您读取的字节数超过最大邮件大小时,需要重新同步。

我看到一些通讯管理员放下并重新建立连接(重新开始),其他人则丢弃数据,直到他们能够恢复同步。然后,您将获得是否需要保证交付和重新传输的乐趣。

最好的协议是简单的协议。创建一个消息头,其中包含一个SOH字节,两个字节的消息长度(或任何适当的),一个2字节的消息类型和一个字节的消息子类型。您也可以使用任意数量的字节结束消息。看一下ASCII图表,自终端日以来,有许多十六进制字节00-1F是非常标准的。

在这里重新发明轮子毫无意义。使其更容易,因为您知道此消息应该有多长,而不是在数据中查找模式。

答案 2 :(得分:-2)

听起来你需要把它当作字节流处理并缓冲数据包,直到你看到你的EOF代码0x2300。