Java非阻塞IO ObjectStream

时间:2016-03-24 21:16:08

标签: java sockets tcp java-8 nio

我已经看到有关于这个主题的一些问题,但它们都是几年或者不是很精细。

我一直在将旧的Socket应用程序迁移到新的NIO SocketChannel,因为它工作不稳定,我将再次执行此部分(作为代码审查的一部分)。所以现在我正在使用非阻止SocketChannel,并且发现我不能只使用ObjectInputStreamObjectOutputStream因为......它是非阻塞的。 显然,SocketChannel需要具有传输数据的大小。

是否有关于此问题的已知解决方案?是否可以使用模板,或者通常被认可为最佳实践的解决方案(模式)?我可以利用ObjectInputStreamObjectOutputStream这一事实使一切变得更加轻松。如果我必须创建自己的实现,我可能需要花费太多时间在应用程序中打破很多东西,我试图让它更稳定。

摘要中的问题:

  • 是否有一个在非阻塞ObjectInputStream中使用ObjectOutputStreamSocketChannel的常见解决方案?
  • 我甚至可以制作一个混合,比如在非阻塞模式下接受传入连接,当选择器发现有东西需要读取时,它会变成阻塞模式吗? (我知道这听起来很糟糕,但我有点绝望。)

PS:使用Java 8,它是一个TCP-Stream。

2 个答案:

答案 0 :(得分:2)

  

我正在使用Non-Blocking SocketChannel,并且发现我不能只使用ObjectInputStream和ObjectOutputStream,因为......它是非阻塞的。

SocketChannel默认是阻止的。如果您不想要非阻塞,请不要这样配置。

ObjectInputStream和ObjectOutputStream可以更简单地与普通Java IO一起使用。

  

显然,SocketChannel需要具有传输数据的大小。

您不必,但如果您使用的是Object * Stream则更简单。

  

是否有关于此问题的已知解决方案?

使用普通IO,或者在使用NIO之前使用一段长度的数据。

如果您想提高性能,我建议您使用另一个序列化库。内置的是最慢的选项之一。有几十个替代品(实际上我写了两个;)

  

是否可以使用模板,或者通常被批准为最佳实践(模式)的解决方案?

使用Plain IO和更快的序列化程序。

  

我可以利用ObjectInputStream和ObjectOutputStream这一事实使一切变得更加容易。

在这种情况下,您不希望使用NIO,因为它会使事情变得十倍,尤其是如果您使用非阻塞IO和选择器。

  

如果我必须创建自己的实现,我可能需要花费太多时间在应用程序中打破很多东西,我试图让它更稳定。

同意,特别是当有很多选择的选择时。

  

是否有一个在非阻塞SocketChannel中使用ObjectInputStream和ObjectOutputStream的通用解决方案?

完全没有。

  

我甚至可以制作一个混合,比如在非阻塞模式下接受传入的连接,当选择器发现有东西需要读取时,它会变成阻塞模式吗? (我知道这听起来很糟糕,但我有点绝望。)

当然,就像我说的那样,SocketChannel默认是阻塞的,所以你不需要做任何事情。我也会让受体阻塞。

  

PS:使用Java 8,它是一个TCP-Stream。

没问题,如果您使用的是Java 1.4,那就相同了。这些图书馆在过去12年中没有发生太大变化。

答案 1 :(得分:0)

使用包裹ObjectOutputStream的{​​{1}}序列化您的对象,然后获取生成的ByteArrayOutputStream缓冲区。通过SocketChannel发送缓冲区。

在另一端,从byte[]中提取byte[]缓冲区,构建SocketChannelByteArrayInputStream,然后阅读您的对象。