2013-12-23 72 views
5

查看JDK 1.7 API。我似乎無法在AsynchonousSocketChannel上設置連接超時。無論如何,我可以在這樣的頻道上設置連接超時嗎?如何設置Java NIO AsynchronousSocketChannel連接超時

謝謝。

+1

超時用於阻止操作。這是一個異步操作。這個問題沒有意義。 – EJP

+0

@EJP - 從不想永遠等待套接字連接的角度來看,即使您的操作是異步的。也就是說,要做到這一點很棘手,即使在C中也是如此。您必須在非阻塞模式下使用帶有超時的'select()'。我真的不得不挖掘出如何用NIO2來做到這一點 - 在這種情況下,如何將它們全部從你身上抽象出來,甚至是不可能的。 –

+0

@Brian沒有'永遠等待'。默認連接超時大約一分鐘,與平臺有關。我知道如何在阻塞和非阻塞模式下完成它,謝謝,並且我同意你在下面的答案中的陳述,即在給定現有Java API的情況下你不能以異步模式工作。他們應該已經爲connect方法提供了一個超時參數,這樣'CompletionHandler'可以被更早的調用(注意無論你在哪個級別使用什麼技術,你只能減少連接超時,而不能增加它)。 – EJP

回答

5

答案是:你不行。

首先要了解的是TCP連接的工作原理。內核正在發送SYN數據包,取消每次重試之間的時間。這可以通過內核參數進行調整。覆蓋對此進行了詳細(Linux)的一篇文章,可以發現here

爲了給你一個什麼樣的參與,以實現自己的超時套接字的想法連接是把插座非阻塞模式,把它扔到一個select()超時,然後使用getsockopt()來查看發生了什麼。 This StackOverflow answer顯示了這是如何工作的。

使用NIO.2,將使用您無權訪問的線程爲您處理連接過程。不幸的是,沒有辦法告訴它你想在連接上縮短超時時間;它只是調用您的完成處理程序/當連接失敗(包括超時)成功時通知Future

你確實有調用返回的Futureget(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監聽器。