查看JDK 1.7 API。我似乎無法在AsynchonousSocketChannel上設置連接超時。無論如何,我可以在這樣的頻道上設置連接超時嗎?如何設置Java NIO AsynchronousSocketChannel連接超時
謝謝。
查看JDK 1.7 API。我似乎無法在AsynchonousSocketChannel上設置連接超時。無論如何,我可以在這樣的頻道上設置連接超時嗎?如何設置Java NIO AsynchronousSocketChannel連接超時
謝謝。
答案是:你不行。
首先要了解的是TCP連接的工作原理。內核正在發送SYN數據包,取消每次重試之間的時間。這可以通過內核參數進行調整。覆蓋對此進行了詳細(Linux)的一篇文章,可以發現here
爲了給你一個什麼樣的參與,以實現自己的短超時套接字的想法連接是把插座非阻塞模式,把它扔到一個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
監聽器。
超時用於阻止操作。這是一個異步操作。這個問題沒有意義。 – EJP
@EJP - 從不想永遠等待套接字連接的角度來看,即使您的操作是異步的。也就是說,要做到這一點很棘手,即使在C中也是如此。您必須在非阻塞模式下使用帶有超時的'select()'。我真的不得不挖掘出如何用NIO2來做到這一點 - 在這種情況下,如何將它們全部從你身上抽象出來,甚至是不可能的。 –
@Brian沒有'永遠等待'。默認連接超時大約一分鐘,與平臺有關。我知道如何在阻塞和非阻塞模式下完成它,謝謝,並且我同意你在下面的答案中的陳述,即在給定現有Java API的情況下你不能以異步模式工作。他們應該已經爲connect方法提供了一個超時參數,這樣'CompletionHandler'可以被更早的調用(注意無論你在哪個級別使用什麼技術,你只能減少連接超時,而不能增加它)。 – EJP