Java Socket網絡編程常見異常(轉)

轉:https://www.cnblogs.com/qq78292959/p/5085559.htmlhtml

 

1.java.net.SocketTimeoutExceptionjava

  這個異常比較常見,socket超時。通常有2個地方會拋出這個:
    a.一個是connect的時候,這個超時參數由connect(SocketAddress endpoint, int timeout)中的後者來決定,
              b.還有就是setSoTimeout(int timeout),這個是設定讀取的超時時間。他們設置成0均表示無限大。
-----------------------------------------------------------------------------------------------------
2.java.net.BindException:Address already in use:JVM_Bind
該異常發生在服務器端進行new ServerSocket(port)或者socket.bind(SocketAddress bindpoint)操做時。

緣由:與port同樣的一個端口已經被啓用,並進行監聽。
此時用netstat -an 命令,能夠看到一個Listening狀態的端口。
只須要找到一個沒有被佔用的端口就能解決這個問題。
------------------------------------------------------------------------------------------------------
3.java.net.ConnectException:Connection refused:connect
 
該異常發生在客戶端進行new Socket(ip, port)或者socket.connect(address, timeout)操做時。
 
緣由:指定ip地址的機器不能找到(也就是說從當前機器不存在到指定ip路由),
或者是該ip存在,但找不到指定的端口進行監聽。應該首先檢查客戶端的ip和port
是否寫錯了,假如能ping通(服務器端把ping禁掉則須要另外的方法),則看在服務器端的監聽指定端口的程序是否啓動。

--------------------------------------------------------------------------------------------------------
4.java.net.SocketException:Socket is closed
該異常在客戶端和服務器端都可能發生。異常的緣由是己方主動關閉了鏈接後
(調用了Socket的close方法)再對網絡鏈接進行讀寫操做。
 
------------------------------------------------------------------------------
5.java.net.SocketException: Connection reset或者Connect reset by peer:Socket write error
該異常在客戶端和服務器端均有可能發生,引發該異常的緣由有兩個,
  a. 第一個就是假如一端的Socket被關閉(或主動關閉或者由於異常退出而引發的關閉), 另外一端仍發送數據,發送的第一個數據包引起該異常(Connect reset by peer)。
       b. 另外一個是一端退出,但退出時並未關閉該鏈接,另外一端假如在從鏈接中讀數據則拋出該異常(Connection reset)。
 
簡單的說就是在鏈接斷開後的讀和寫操做引發的。 對於服務器,通常的緣由能夠認爲:
   a) 服務器的併發鏈接數超過了其承載量,服務器會將其中一些鏈接主動Down掉.
   b) 在數據傳輸的過程當中,瀏覽器或者接收客戶端關閉了,而服務端還在向客戶端發送數據。
 
----------------------------------------------------------------------------
6.java.net.SocketException: Broken pipe
該異常在客戶端和服務器均有可能發生。在拋出SocketExcepton:Connect reset by peer:Socket write error後,假如再繼續寫數據則拋出該異常。前兩個異常的解決方法是首先確保程序退出前關閉全部的網絡鏈接,其次是要檢測對方的關閉鏈接操做,發現對方 關閉鏈接後本身也要關閉該鏈接。
對於4和5這兩種狀況的異常,須要特別注意鏈接的維護。在短鏈接狀況下還好,若是是長鏈接狀況,對於鏈接狀態的維護不當,則很是容易出現異常。
 
  基本上對長鏈接須要作的就是:
    a) 檢測對方的主動斷連(對方調用了Socket的close方法)。由於對方主動斷連,另外一方若是在進行讀操做,則此時的返回值是-1。因此一旦檢測到對方斷連,則主動關閉己方的鏈接(調用Socket的close方法)。
    b) 檢測對方的宕機、異常退出及網絡不通,通常作法都是心跳檢測。雙方週期性的發送數據給對方,同時也從對方接收「心跳數據」,若是連續幾個週期都沒有收到對 方心跳,則能夠判斷對方或者宕機或者異常退出或者網絡不通,此時也須要主動關閉己方鏈接;若是是客戶端可在延遲必定時間後從新發起鏈接。雖然Socket 有一個keep alive選項來維護鏈接,若是用該選項,通常須要兩個小時才能發現對方的宕機、異常退出及網絡不通。
----------------------------------------------------------------------------------------------
7.java.net.SocketException: Too many open files
 緣由: 操做系統的中打開文件的最大句柄數受限所致,經常發生在不少個併發用戶訪問服務器的時候。
由於爲了執行每一個用戶的應用服務器都要加載不少文件(new一個socket就須要一個文件句柄),這就會致使打開文件的句柄的缺少。 
 
解決方式: 
a) 儘可能把類打成jar包,由於一個jar包只消耗一個文件句柄,若是不打包,一個類就消耗一個文件句柄。
 b) java的GC不能關閉網絡鏈接打開的文件句柄,若是沒有執行close()則文件句柄將一直存在,而不能被關閉。
也能夠考慮設置socket的最大打開 數來控制這個問題。對操做系統作相關的設置,增長最大文件句柄數量。ulimit -a能夠查看系統目前資源限制,ulimit -n 10240則能夠修改,這個修改只對當前窗口有效。
相關文章
相關標籤/搜索