3

在我的 Java NIO 实现中,我无法让 SelectionKey.attach() 工作。基本上,一旦客户端连接(OP_ACCEPT 兴趣操作),我将它们添加到映射中,其中它们的 IP 地址映射到维护客户端状态的对象。然后,当发生 OP_READ 时,我再次检索客户端的 IP 地址,这次从映射中获取值并以这种方式获取客户端的状态对象。

这里的问题是,每次从网络读取数据时,我都必须进行地图查找。那里有很多浪费的工作。因此,我很高兴看到您可以将任意对象类型附加到 SelectionKey,当您调用 SelectionKey.attachment() 时应该很容易检索到,即使我们现在正在处理不同的事件(在 OP_READ 期间检索而不是放入在 OP_ACCEPT 期间映射)。

问题是它不起作用。当我检索附件时,它始终为空。如果我通过 attach() 设置附件,然后立即调用 attachment(),它确实有效。不知何故,在不同的事件之间,它失去了关联。

对不起,我的代码在这里发布有点长,但是如果您查看此线程中的评论: 链接文本 ...您会看到其他一些人基本上得出了相同的结论:即 attach() 和attachment() 不起作用,而且从来没有。

是否有让它工作的技巧,或者我是否坚持在每次有新的读取事件要处理时手动在地图中进行查找所必需的邪恶开销?

最后,有没有办法在一个新的子类中“包装”SelectionKey 来正确处理attach() 和attachment()?

谢谢!

4

2 回答 2

6

我已经成功地将对象附加到 SelectionKeys 上,没有任何问题,但只能来自同一个事件。例如,当我第一次得到一个OP_READ时,我将一个对象附加到 SelectionKey 并在随后的读取中检索它,它工作正常。也许OP_ACCEPTOP_READ处理不同的键,因为它们是不同的事件,但我认为对于同一个连接,SelectionKey 应该是相同的......但是,如果你即使从同一个 IP 进行不同的连接,你也会得到不同的 SelectionKey。

更新:我刚刚检查了我的代码,有一些非常重要的事情:我根本没有调用 attach();我用的 SelectableChannel.register(Selector sel, int ops, Object att)方法。如果您这样做,随后对 SelectionKey 上的 attachment() 的调用将起作用。

于 2009-08-21T06:07:06.027 回答
1

您的链接页面中没有 CR,我在bugs.sun.com 上看不到任何内容。然而,attach/是非常简单的代码(虽然在我的bugattachment之后稍微复杂一些。我猜你得到了一个不同的,所以试图包装它是没有意义的。SelectionKey

于 2009-08-21T04:51:56.723 回答