使用java.nio选择非阻塞问题

时间:2010-11-20 11:12:26

标签: java multithreading sockets nio

我刚刚开始使用java.nio并且可能使用了一些错误的方法,所以我遇到了一些问题。

我正在尝试编写像Port Forwarder这样的东西,它可以使用各种附加模块修改通过它的流量。

以下是我的表现:

  1. ConnectionManager - 一个线程 拥有它自己的选择器 注册到OP_ACCEPT ServerSocketChannel实例。无论什么时候 选择任何东西 - 它创造一个 ConnectionProcessor对象即 管理连接。

  2. ConnectionProcessor - 一个线程 打开SocketChannel 预定义的前向点(在哪里 从新发送数据包 连接客户端)。然后它打开 它是自己的选择器并注册它 到客户端的SocketChannel的OP_READ 和服务器的SocketChannel的 OP_READ。

  3. 然后处理器进入无限循环,从选择器中选择数据并适当地转发它。要确定将数据发送到何处,它会将SelectionKey.channel()与clientChannel和serverChannel进行比较。

    ConnectionProcessor中的选择是使用5秒的超时(select(5000)) - 来处理超时。当选择超时时 - 它尝试从两个通道读取以获得异常或-1结果。

    现在我的问题是:

    1. 使用key.cancel()是否正确 处理完钥匙后?最 我在互联网上看过的例子 只需从中删除密钥即可 selectedKeys()列表。 key.cancel() 似乎是更好的方法。
    2. 有几个是正确的 基本上使用的选择器 相同的ServerSocketChannel?或者我应该总是使用单个选择器并传递选定的键 适当的经理人?我是什么 意思是如果3个客户连接 同时这是什么 会发生:

      a)经理创建处理器。 处理器打开客户端通道 处理器注册它自己 选择器到客户端通道。 b) 重复(a)c)重复 (a)中

    3. 由于某种原因,即使一个客户端连接到我的转发器 - 它也不会处理 消息超过5000毫秒超时。它开始选择,锁定5秒,然后去 到第二次迭代并获取我在上一次超时期间收到的5-6条消息。 我应该责备(1),(2)还是其他一些原因?
    4. 是否有关于这些内部所有内容如何工作的手册?我完全理解下面的机制之后才会理解如何使用东西。阅读API没有帮助,因为它是为已经知道使用nio的正确方法的人编写的。
    5. 感谢您阅读我的整个问题,并提前感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

  1. 没有。只需从所选集中删除密钥即可。通常这是通过iterator.remove()完成的。如果您取消它们,则永远不会再次选择它。

  2. 这是毫无意义的。您不需要第二个选择器或额外的线程。这就是NIO的用途。您可以使用原始帖子中的原始选择器处理所有内容。

  3. 这可能是由奇怪的代码引起的。如上所述重做它,看看它是否仍然发生。如果是这样,请在此处发布一些代码。

  4. 您需要阅读伯克利套接字API或一本好书,如史蒂文斯,Unix网络编程或我的;-)