Java中的非阻塞套接字写入与阻塞套接字写入相比

时间:2011-11-10 21:57:58

标签: java sockets networking tcp nio

为什么有人更喜欢阻止写入非阻塞写入?我的理解是,如果你想确保另一方在写入方法返回后得到TCP数据包,你只想要阻塞写入,但我甚至不确定是否可能。您必须刷新并且flush必须刷新底层操作系统写入套接字缓冲区。那么非阻塞套接字写入有什么缺点吗?有一个大的底层写入套接字缓冲在性能方面是一个坏主意吗?我的理解是,底层套接字写缓冲区越小,你就越有可能遇到慢/错误的客户端,并且在底层套接字缓冲区已满并且isWritable()返回false时,必须在应用程序级别中丢弃/排队数据包。

2 个答案:

答案 0 :(得分:6)

  

我的理解是,如果你想确保在写入方法返回后另一方获得TCP数据包,你只想要阻塞写入

您的理解不正确。它无法确保。

阻塞写入阻塞,直到所有数据都已传输到套接字发送缓冲区,并从中异步传输到网络。如果读取器很慢,他的套接字接收缓冲区将填满,这最终会导致套接字发送缓冲区填满,这将导致阻塞写入阻塞,阻塞整个线程。非阻塞I / O为您提供了一种检测和处理这种情况的方法。

答案 1 :(得分:3)

非阻塞写入的问题是,如果写入不完整,您可能没有任何有用的操作。你最终可以使用像

这样的循环
// non-blocking write
while(bb.remaining() > 0) sc.write(bb);

OR

// blocking write
sc.write(bb);

第一个可以刻录CPU,第二个可能更合适。

最大的问题是读取。一旦确定是要阻塞还是非阻塞读取,您的写入必须相同。不幸的是,没有办法让它们与众不同。如果您想要非阻塞读取,则必须进行非阻塞写入。