【问题标题】:How to set Java NIO AsynchronousSocketChannel connect timeout如何设置 Java NIO AsynchronousSocketChannel 连接超时
【发布时间】:2014-01-12 05:11:03
【问题描述】:

查看 JDK 1.7 API。我似乎无法在 AsynchonousSocketChannel 上设置连接超时。无论如何我可以在这样的频道上设置连接超时吗?

谢谢。

【问题讨论】:

  • 超时用于阻塞操作。这是一个异步操作。这个问题没有意义。
  • @EJP - 从不想永远等待套接字连接的角度来看,即使您的操作是异步的。也就是说,即使在 C 语言中,这也很棘手。您必须使用 select() 和非阻塞模式下的套接字超时。我真的必须深入研究如何使用 NIO2 来做到这一点——考虑到这一切是如何从你身上抽象出来的,这甚至可能是不可能的。
  • @Brian 没有“永远等待”。默认连接超时时间约为一分钟,具体取决于平台。我知道如何在阻塞和非阻塞模式下执行此操作,谢谢,并且我同意您在下面的回答中的陈述,即鉴于现有的 Java API,您不能处于异步模式。他们应该为 connect 方法提供了一个超时参数,以便可以更早地调用 CompletionHandler(请注意,无论您在什么级别使用任何技术,都只能减少连接超时,而不能增加它)。
  • @EJP 抱歉,我并不是要暗示 you 没有......当我发表评论时,这部分是作为 OP 的一般性声明 /其他读者,然后我决定回答 Q。同意他们应该将其包含在 API 中。并澄清“永远等待”意味着默认超时。
  • @Brian 我认为 NIO2 API 缺少的是异步选择器(WSAAsyncSelect()WSAEventSelect()),这就是您必须在 Winsock 中实现它的方式。也许它们只存在于 Winsock:我不熟悉 Unix 异步 API。

标签: java sockets asynchronous connect nio


【解决方案1】:

答案是:你不能。

首先要了解 TCP 连接的工作原理。内核正在发送 SYN 数据包,并回退每次重试之间的时间。这可以通过内核参数进行调整。可以在here找到一篇详细介绍此内容的文章(适用于 linux)@

为了让您了解为套接字连接实现自己的更短超时所涉及的内容是将套接字置于非阻塞模式,将其放入 select() 并设置超时,然后使用getsockopt() 看看发生了什么。 This StackOverflow answer 展示了它是如何工作的。

在 NIO.2 中,连接过程是使用您无权访问的线程为您处理的。不幸的是,没有办法告诉它你想要更短的连接超时。它只是调用您的完成处理程序/在连接成功或失败(包括超时)时通知Future

您可以选择在返回的Future 上调用get(timeout, unit),然后在超时时取消Future...但这意味着如果您希望连接异步,则必须添加另一层线程/回调,也可以用 nio 实现你自己的异步。

最后一件事值得一提,因为您正在查看异步网络的东西,Netty 确实给了您这个(使用 Nio):

Bootstrap bootstrap = new Bootstrap()
            .group(new NioEventLoopGroup())
            .channel(NioSocketChannel.class)
            .remoteAddress(new InetSocketAddress(remoteAddress, port))
            .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, connectionTimeout);

ChannelFuture f = bootstrap.connect();

您可以使用该ChannelFuture 注册一个侦听器以进行回调。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-17
    • 1970-01-01
    相关资源
    最近更新 更多