日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

new Socket(host, port)阻塞解決

作者:jzlhll123 更新時間: 2022-08-30 編程語言

如果服務器沒有開啟host,port。而客戶端
new Socket(host, port),則會產生阻塞。
這樣的話,我們甚至都沒法關閉這個socket。
找了半天百度沒有合理的解釋,甚至有人說,強行stop Thread,我也是醉了。

正確代碼如下:

//Socket client = new Socket(host, ip); //卡柱啦!不好啦怎辦?

//正確搞法
//1. 直接new一個空的出來,這樣不會卡柱。
Socket client = new Socket();
//2. 按照new Socket(host, port)的二次構造函數,調用
InetSocketAddress address = host != null ? new InetSocketAddress(host, port) :
         new InetSocketAddress(InetAddress.getByName(null), port);
SocketAddress localAddr = null;
try {
     if (localAddr != null) //可以移除
         client.bind(localAddr);
     //3. 關鍵的,我們可以這里設置timeout。
     //即使不做timeout,我們可以在想關閉的時候,調用client.close也可以解決啦。
     client.connect(address, 500);
 } catch (IOException | IllegalArgumentException | SecurityException e) {
     try {
         client.close();
     } catch (IOException ce) {
         e.addSuppressed(ce);
     }
     throw e;
 }

閱讀一下socket的源碼,大致理解了。
Socket類只是通過包裝模式,創建和調用SocketImpl的方法。
查看new Socket(host, port)就可以看到在構造函數就進行了createImpl() -> impl.connect(xx, timeout)導致了阻塞,所以無法返回Socket給你。因此這種情況,你確實沒有很好的辦法去停止socket。只能把線程弄死了。

而類似的,我們按照上述我改造后的來使用,new Socket(),我們就得到了Socket對象。
在connect之前內部也確保得到了impl。

因此首先抄下我剛剛的代碼,然后,想要解決阻塞問題,就有了2個合理的方案:

  1. client.connect(addr, timeout)的時候,我們可以設置第二個參數timeout,來保證連接的時候自動超時;
  2. client.connect(addr), 不做超時處理;我們也可以使用socket.close()來關閉。

原文鏈接:https://blog.csdn.net/jzlhll123/article/details/126169193

欄目分類
最近更新