【发布时间】:2013-01-11 18:02:28
【问题描述】:
我在从 TCP 套接字获取所有数据时遇到了一些麻烦。
在我的服务器中,我正在从这样的套接字读取数据:
int len;
byte[] buffer = new byte[2000];
try {
this.in = new DataInputStream(this.socket.getInputStream());
this.out = new DataOutputStream(this.socket.getOutputStream());
running = true;
while (running) {
len = in.read(buffer);
if (len < 0) {
running = false;
} else {
parsePacket(buffer, len);
}
}
} catch (IOException ex) {
System.out.println("Catch IOException: " + ex);
ex.printStackTrace();
} finally {
try {
System.out.println("Closing");
in.close();
out.close();
socket.close();
} catch (IOException ex) {
System.out.println("Finally IOException: " + ex);
}
}
数据包格式是这样的:
[标题][数据][终结者]
- 标头 --> 标识消息开头的字符序列(没有关于数据包长度的信息);
- Data --> 被分割成段,如:[Size Seg. 1][数据段。 1][尺寸段。 2][数据段。 2][尺寸段。 3][数据段。 3]....[尺寸段。 N][数据段。 N]
- 终结者 --> [0x00]
数据的接收速度非常快(有时 200 毫秒或更短),所以有时read(buffer) 会在buffer 中填充如下消息:
- [HEADER1][DATA1][TERM1] 或,
- [HEADER1][DATA1][TERM1][HEADER2][DATA2][TERM2].............[HEADER N][DATA N][TERM N] 或,李>
- [HEADER1][DATA1][TERM1][HEADER2][DATA2][TERM2]................[HEADER N][DAT(最后一条消息不完整)
parsePacket() 方法能够解析具有上述格式的消息,如果接下来有更多消息,它们也将被解析(递归)。但是如果最后一条消息不完整,它不会解析它(我不希望这样,但直到现在我还没有找到合适的解决方案)。
消息中的数据存储在 MySQL 数据库中(使用 JDBC 驱动程序)。消息的每次解析都可能涉及对数据库的多个查询。由于我只使用一个线程来接收、解析和存储数据,因此代码的执行速度并没有达到应有的速度……应该尽快接收和存储数据。
我想讨论的几点:
- 在不丢失部分消息的情况下获取所有消息的最佳方法是什么?
- 如何改进接收和存储数据的方式? (应尽快存储数据!)
【问题讨论】:
-
请记住,TCP 是一种流 协议,而不是数据包协议。这意味着您可能不会在一次接听电话中收到所有消息,或者您可能会收到多条消息。