在我使用 java nio 的程序中,当尝试连续写入 10 KB 消息时,socketchannel.write() 变得非常慢。写入完整 10 KB 消息的测量时间在 160 毫秒到 200 毫秒之间。但写入完整的 5 KB 消息只需要 0.8 毫秒。
在选择器中,我只有Selection.OP_READ,不处理Selection.OP_WRITE。当收到一个大的完整消息时,它会被写入另一个接收者 4 次。
有人有同样的问题吗?有一篇关于 socketchannel.write() 慢的文章。我的问题是如何在 OP_READ 和 OP_WRITE 之间交替更改?
如果我添加一个间隔,例如 150 毫秒,响应时间就会缩短。有什么方法可以找到缓冲区何时已满,以便我可以让程序等待。我的操作系统是windows xp。
谢谢。
我按照 EPJ 建议检查写入的字节数。但响应时间仍然很高。我在这里贴出我的部分代码,想检查一下我的代码是否有问题。
//这是使用 nio 的 writeData() 部分:
while (buffer.hasRemaining()) {
try {
buffer.flip();
n = socket.write(buffer);
if(n == 0) {
key.interestOps(SelectionKey.OP_WRITE);
key.attach(buffer);
break;
}
} catch (IOException e) {
e.printStackTrace();
} finally {
buffer.compact();
}
}
if(buffer.position()==0) {
key.interestOps(SelectionKey.OP_READ);
}
最佳答案
我建议您的读取过程很慢,这会导致其接收缓冲区备份,从而导致您的发送缓冲区备份,从而使您的发送停止。
或者您没有正确编写非阻塞模式的代码。如果从 write() 方法得到零结果,则必须 (a) 将interestOps 更改为 OP_WRITE 并 (b) 返回到 select 循环。当你得到 OP_WRITE 时,你必须重复写入;如果您写入了所有数据,请将interestOps更改回OP_READ,否则保留所有内容并等待下一个OP_WRITE。如果您尝试在非阻塞模式下写入时循环,即使存在零长度写入,您也只会旋转,浪费 CPU 周期和时间。
模错误:
while (buffer.position() > 0)
{
try
{
buffer.flip();
int count = ch.write(buffer);
if (count == 0)
{
key.interestOps(SelectionKey.OP_WRITE);
break;
}
}
finally
{
buffer.compact();
}
}
if (buffer.position() == 0)
{
key.interestOps(SelectionKey.OP_READ);
}
关于java - 当消息大小很大时,socketchannel.write() 会变得非常慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8042212/