【问题标题】:Write contents of an InputStream (blocking) to a non-blocking socket将 InputStream 的内容(阻塞)写入非阻塞套接字
【发布时间】:2011-04-05 07:38:06
【问题描述】:

我正在编写一个简单的 Java NIO 服务器并且有点头疼:我得到了正常的InputStreams 我需要通过管道传递给我的客户。我有一个线程执行所有写入,所以这会产生一个问题:如果 InputStream 阻塞,所有其他连接写入将被暂停。

我可以使用InputStream.available() 来检查是否有任何传入数据我可以在不阻塞的情况下读取,但如果我已经到达流尾,我似乎必须调用read()知道。

这让我很头疼,但我不敢相信我是第一个遇到这个问题的人。

目前为止我想到的唯一选择:

  • 为每个InputStream 设置一个单独的线程,但这很愚蠢,因为我首先使用的是非阻塞 I/O。我也可以有一个线程池来执行此操作,但这又限制了我可以将InputStream 传送到的同时客户端的数量。
  • 有一个单独的线程在超时的情况下读取这些流(如果读取持续时间超过一定时间,则使用另一个线程中断),但是如果我有很多打开的InputStream,那肯定会阻塞数据流不提供数据。

当然,如果有魔法InputStream.isEof()isClosed() 那么这根本不是问题:'(

【问题讨论】:

  • 使用阻塞IO一点也不傻。您可以使用它获得相同或更好的性能。你知道这实际上是一个问题吗?
  • 是的,服务器需要支持大量的持久连接(20,000+)。
  • 您不能以非阻塞方式使用 InputStream,也无法解决这个问题。我建议您更换为您提供 InputStream 的系统或像您所做的那样使用多个线程。这些线程可以有多少个?如果它小于 1K,我不会担心。
  • 如果您的连接数超过 10K,您是否考虑过使用多个服务器?
  • 当然可以使用多个服务器,但我需要更多的编码,因为一些连接通过服务器相互通信。当然,没有什么是不可能的,但我宁愿不重写整个事情:)——而且我的预算有限。

标签: java inputstream nio


【解决方案1】:

".....每个 InputStream 都有一个单独的线程,但这很愚蠢,因为我首先使用的是非阻塞 I/O...."

一点也不傻。首先,您需要检查是否可以从 InputStream 实现中检索 SelectableChannel。如果是这样,你很幸运,你可以用选择器注册它并照常做。但是很有可能您的 InputStream 可能有一个不是 SelectableChannel 的通道,在这种情况下,“为每个 InputStream 设置一个单独的线程”是显而易见的事情,而且可能是正确的事情。

请注意,SO 中讨论了关于not able to get a SelectableChannel from an inputstream 的类似问题。不幸的是,你被卡住了。

【讨论】:

  • 谢谢,我想我现在得到了我需要的东西!
  • '是否可以从 InputStream 实现中检索 SelectableChannel' -- 如果套接字源自 SocketChannel.open() 或 ServerSocketChannel.accept(),则只能从套接字获取通道。它在 Javadoc 中。运气与它无关。
【解决方案2】:

我有一个线程执行所有 写

你有没有停下来考虑这是否是问题的一部分而不是解决方案的一部分?

【讨论】:

  • 每个连接不能有一个线程,因为我需要支持大量的并发连接。
  • @Arne:不合逻辑。如果有合适的硬件和操作系统,你会惊讶于现代 JVM 支持多少线程。
  • 是的,我看到了正在进行的讨论。我没有足够的知识来发表意见,我只需要让它开箱即用,而不需要调整操作系统或任何东西,并且使用少量的 RAM。再说一次,你也可以指出这样的服务器应该用 Erlang 制作,而且我是一个使用 Java 的白痴。这个列表还在继续:)
  • @Peter 绝对是明智的,我可能会这样做,但问题仍然存在:(
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-10-31
  • 2013-10-15
  • 2013-02-23
  • 2011-10-09
  • 1970-01-01
  • 2017-04-18
  • 1970-01-01
相关资源
最近更新 更多