java.net.SocketException: Socket closed解決


如題,在socket編程中報錯java.net.SocketException: Socket closed

1、理解錯誤含義

在數小時無能狂怒后於StackOverflow尋得箴言:

This exception means that you closed the socket, and then continued to try to use it.
你把socket關了,卻還想繼續用,就會報這個錯

2、可能的原因

1. 關閉了IO流(最常見)

也就是說,在你發送、接收操作做完之前別關IO流,也許就能解決;
注意,你可能沒有關閉IO流,或沒有關掉socket的socket.getOutputStream()socket.getInputStream()
但它可能被其他IO流關閉影響而自動關閉
(見2)

后來才知道 socket 只要在 io流close的情況下 自動關閉,意思就是你想邊發送邊接受最正確的方式就是發送和 接受的操作都做完之后 再一起關閉IO流 完美解決。

內容來自博客:https://blog.csdn.net/qq_33431368/article/details/72331128

2. 我沒有關基礎的IO,為什么還是報了這個錯?

常見於在socket中發送了對象的情況,也即使用了ObjectOutputStream
出錯原因:使用完畢的ObjectOutputStream關閉時,會導致其包裝的OutputStream也自動關閉。

我的出錯代碼如下

 try(OutputStream os = socket.getOutputStream(); InputStream is = socket.getInputStream()) { Resource resource = new Resource(); sendResourceObj(resource,os); os.write("exit".getBytes(StandardCharsets.UTF_8)); } } catch (Exception e) { e.printStackTrace(); } 

其中的發送對象的函數如下(本意是為了解耦,把功能盡量模塊化):

public static void sendResourceObj(Resource r,OutputStream os){ try(ObjectOutputStream oos = new ObjectOutputStream(os)) { oos.writeObject(r); oos.flush(); } catch (Exception e) { e.printStackTrace(); } } 

可以看到,在sendResourceObj執行結束后,ObjectOutputStream就關閉了;

修改方法
ObjectOutputStreamOutputStream一同,直接放到try-with-resource的聲明語句中,待使用IO完畢后一起關閉即可

try(OutputStream os = socket.getOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(os); InputStream is = socket.getInputStream()) { Resource resource = new Resource(); oos.writeObject(resource); oos.flush(); os.write("exit".getBytes(StandardCharsets.UTF_8)); } } catch (Exception e) { e.printStackTrace(); } 

初學者記錄一下踩坑經驗,如有錯誤還望路過大佬不吝賜教orz

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM