Java NIO服务器如何读取带有任何头的var-len数据包

时间:2013-08-25 08:04:39

标签: java sockets nio

我正在学习使Minecraft服务器与Bukkit类似,以获得乐趣。我以前处理过NIO但不是很多,而且不是很实际。我现在遇到一个问题,那就是Minecraft有很多可变长度的数据包,并且由于这些数据包没有任何一致的“标题”,NIO正在做这个奇怪的事情,因为数据并不总是立即发送。

我最近了解到这是来自这个帖子的事情:Java: reading variable-size packets using NIO我宁愿不使用Netty / MINA /等。因为我喜欢自己学习这一点,因为我这样做是为了教育,而不是为了使它成为一个巨大的项目。

所以我的问题是,我究竟如何防止这种数据包碎片?我尝试在java.net.Socket#setTcpNoDelay(boolean on)中使用Nagle的算法,但奇怪的是,所有这一切都是为了使每次发送数据包时,它都是碎片化的,而当我启用它时,第一个数据包总是通过OK,然后以下数据包变成碎片。

我非常关注Rox Java NIO Tutorial所以我知道这个代码应该工作,但是该教程只能将字符串消息回送给对等体,而不是复杂的字节流。

这是我的代码。对于某些上下文,我使用Executor#execute(Runnable)来创建两个线程。既然我还在学习线程和并发性,并尝试将它们与网络结合起来,那么对此的任何反馈都将非常受欢迎!!

ServerSocketManager ServerDataManager

非常感谢,我知道这有很多东西可以接受,所以我不能感谢你花时间阅读&响应!!

1 个答案:

答案 0 :(得分:3)

TCP总是一个字节流。当你得到它们或你得到多少时,你无法控制。它可以在任何时间以任何金额进入。这就是协议存在的原因。

标头是协议的常见部分,用于告诉您在获得整个消息之前需要读取多少数据。

所以这里简短的回答是:你做不到。

你说的一切都不想做 - 这就是你必须要做的事情。