对于任何有兴趣的人来说,这个问题的答案是否定的,套接字不会无序地读取缓冲区。
AsynchronousSocketChannel是否可能无序读取字节?我正在调试我的问题开始的地方,我的协议序列化对象高达32k并将它们写入套接字,如下所示:
AsynchronousSocketChannel socket; ...
// serialize packet
ByteBuffer base; // serialized buffer (unknown size, size growns as needed with limit of 32k)
for (int j1 = 0; j1 < 6 && base.remaining() > 0; j1++) { // limit to 6 tries
socket.write(base).get(15, TimeUnit.SECONDS);
if (base.remaining() > 0) {
// aparently, if the write operation could write everything at once, we wouldnt have an issue
}
}
此写操作不是并发的,它与锁同步。我使用标准的读操作:
AsynchronousSocketChannel socket; ...
Future<Integer> reading = socket.read(getReadBuffer()); // the read buffer is 8k big
// consume the buffer also not concurrently
我每秒最多可以写入1000个数据包,每个数据包最多1000个字节而不会出现问题,但最终会有一个或其他客户端中断。如果数据包较大,它可以处理而不会中断的频率会降低,如果我每秒写入8次,那么包含40.000字节的数据包将会中断。
示例:我写了5个字节(1,2,3,4,5),缓冲区足够大,一次写入所有内容但操作决定停止缓冲区中的剩余字节(这应该是正常的TCP行为),所以让我们说操作写了1,2,3,停止并写了剩下的4,5(而buf.remain&gt; 0 {write}),在阅读时,我很可能会先阅读4,5和1,2,3之后,这不应该发生。
虽然在localhost上一切正常但是在同一台机器(仍然是相同的网络/路由器)之外它不会工作。
我没有将缓冲区翻转为写入/读取。我可以确保它不是序列化的问题,服务器和客户端都是单线程的。我忘记做某事了?有关如何解决此问题的任何建议吗?
答案 0 :(得分:0)
如果你真正想要的只是同步I / O,那就不清楚你为什么要使用异步I / O,这就是你从那段代码中获得的。使用普通的SocketChannel
,你会感觉更好。
我没有将缓冲区翻转为写入/读取。
你必须。您必须在flip()
前write()
,之后compact()
,之后&#39;在这种情况下,意思与上述相同。