1. 程式人生 > >Connection reset by peer: socket write error錯誤分析及解決

Connection reset by peer: socket write error錯誤分析及解決

Connection reset by peer: socket write error錯誤分析:

常出現的Connection reset by peer: 原因可能是多方面的,不過更常見的原因是: 
①:伺服器的併發連線數超過了其承載量,伺服器會將其中一些連線Down掉; 
②:客戶關掉了瀏覽器,而伺服器還在給客戶端傳送資料; 
③:瀏覽器端按了Stop 

通常原因為:遠端主機上對等方應用程式突然停止執行,或遠端主機重新啟動,或遠端主機在遠端方套接字上使用了“強制”關閉 (參見setsockopt(SO_LINGER))。另外,在一個或多個操作正在進行時,如果連線因“keep-alive”活動檢測到一個失敗而中 斷,也可能導致此錯誤。此時,正在進行的操作以錯誤碼WSAENETRESET失敗返回,後續操作將失敗返回錯誤碼WSAECONNRESET。
但是如果頻繁出現,就表示很 多客戶端連線到Apache伺服器的響應時間太長了,可能是網路的問題或者伺服器效能問題。



網友分析:



樓主
   要從一個被遮蔽的網站上下載一些東西,於是寫了一個Servlet,將它傳到了一臺境外的伺服器上.
讓這臺伺服器去下載指定的資源,然後再回傳給我.相當於一個代理吧.

JAVA code
public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String url = request.getParameter("url"); //得到要下載的資源的URL.

        if (!StringUtils.isNullOrEmpty(url)) {
            System.out.println(url);
            URL u = new URL(url);
            URLConnection conn = u.openConnection();

            try { ///把響應頭設定成一樣的.
                for (Map.Entry<String, List<String>> m : conn.getHeaderFields()
                        .entrySet()) {
                    if (m != null && m.getKey() != null && m.getValue() != null
                            && m.getValue().size() > 0) {
                        response.setHeader(m.getKey(), m.getValue().get(0));
                    }
                }
            } catch (Exception e) {
                // TODO: handle exception
                e.printStackTrace();
                CommonLog.log.warn(e);
            }

            InputStream in = conn.getInputStream(); //從 connection得到inputstream
            OutputStream out = response.getOutputStream(); //得到向客戶端的輸出流
            try {
                IOUtils
                        .wr
IT
e(conn.getInputStream(), response .getOutputStream()); //寫資料. } catch (Exception e) { e.printStackTrace(); // TODO: handle exception CommonLog.log.warn(e); if (in != null) { in.close(); } if (out != null) { out.close(); } } } }


IOUtils.wrITe()程式碼如下:

JAVA code
    /**
     * 從input裡面讀取資料然後寫入output,讀完後自動關閉流。
     * @param input inputStream
     * @param output outputStream
     * */
    public static void write(InputStream input, OutputStream output)
            throws IOException {
        write(input,output,true);
    }

    /**
     * 自動從inputstream裡面讀資料,然後寫到outputstream裡面去。
     * @param input inputstream
     * @param output outputstream
     * @param close 讀完後是否自動關閉流。
     * */
    public static void write(InputStream input, OutputStream output,boolean close)
            throws IOException {
        byte[] b = new byte[1024];
        int len = input.read(b);
        while (len != -1) {
            output.wrITe(b, 0, len);
            len = input.read(b);
        }
        
        output.flush();
        if (close) {
            input.close();    
            output.close();
        }
    }


將程式傳到伺服器上以後,在伺服器上訪問
http://localhost:8080/test/down?url=http://www.xxx.com/z.zip
可以下載成功.

但是當遠端訪問的時候,就會出現
JAVA.NET.SocketException:  Connection reset by peer: socket wrITe error

假設伺服器IP是2.2.2.2吧.

訪問
http://2.2.2.2:8080/test/down?url=http://www.xxx.com/z.zip
就會出現上面的那個錯誤.
注意,我並沒有關閉瀏覽器或者按停止按鈕.只要一打上那個地址就會出錯.


錯誤發生在:

JAVA code
output.wrITe(b, 0, len);//執行這行程式碼的時候.


具體的錯誤資訊如下:


JAVA code
ClientAbortException:  java.net.SocketException: Connection reset by peer: socket write error
    at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:366)
    at org.apache.tomcat.util.buf.ByteChunk.flushBuffer(ByteChunk.java:432)
    at org.apache.tomcat.util.buf.ByteChunk.append(ByteChunk.java:347)
    at org.apache.catalina.connector.OutputBuffer.writeBytes(OutputBuffer.java:392)
    at org.apache.catalina.connector.OutputBuffer.write(OutputBuffer.java:381)
    at org.apache.catalina.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:89)
    at com.joejoe.utils.IOUtils.write(IOUtils.java:62)
    at com.joejoe.utils.IOUtils.wrITe(IOUtils.java:48)
    at com.tqsoft.wdys.other.getMegavideo.doGet(getMegavideo.java:79)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:627)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:269)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
    at com.joejoe.utils.WEB.CharSetFilter.doFilter(CharSetFilter.java:39)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:172)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:108)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:174)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:875)
    at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BASEProtocol.java:665)
    at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:528)
    at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:81)
    at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:689)
    at java.lang.Thread.run(Unknown Source)
Caused by: java.net.SocketException: Connection reset by peer: socket write error
    at java.net.SocketOutputStream.socketWrite0(Native Method)
    at java.net.SocketOutputStream.socketWrITe(Unknown Source)
    at JAVA.NET.SocketOutputStream.write(Unknown Source)
    at org.apache.coyote.http11.InternalOutputBuffer.realWriteBytes(InternalOutputBuffer.java:750)
    at org.apache.tomcat.util.buf.ByteChunk.flushBuffer(ByteChunk.java:432)
    at org.apache.tomcat.util.buf.ByteChunk.append(ByteChunk.java:347)
    at org.apache.coyote.http11.InternalOutputBuffer$OutputStreamOutputBuffer.doWrite(InternalOutputBuffer.java:773)
    at org.apache.coyote.http11.filters.IdentityOutputFilter.doWrite(IdentityOutputFilter.java:118)
    at org.apache.coyote.http11.InternalOutputBuffer.doWrite(InternalOutputBuffer.java:583)
    at org.apache.coyote.Response.doWrite(Response.java:560)
    at org.apache.catalina.connector.OutputBuffer.realWrITeBytes(OutputBuffer.JAVA:361)
    ... 27 more


請問如何解決.謝謝.
.
[華 軟 網]
編 程論壇 1 個網友回答:   嘿嘿,陪你一起期待解決方案啦            .
[華 軟 網]
編 程論壇 2 個網友回答:   頂起            .
[華 軟 網]
編 程論壇 3 個網友回答:   幫忙。            .
[華 軟 網]
編 程論壇 4 個網友回答:   我google過 原因我忘了 不過解決方法是用try catch包起來 對這異常不做處理
這樣做確實沒什麼影響 不過是為什麼  我也不是很清楚!            .
[華 軟 網]
編 程論壇 5 個網友回答:   說是這原因 
存在的連線被遠端主機強制關閉。通常原因為:遠端主機上對等方應用程式突然停止執行,或遠端主機重新啟動,或遠端主機在遠端方套接字上使用了“強制”關閉 (參見setsockopt(SO_LINGER))。另外,在一個或多個操作正在進行時,如果連線因“keep-alive”活動檢測到一個失敗而中 斷,也可能導致此錯誤。此時,正在進行的操作以錯誤碼WSAENETRESET失敗返回,後續操作將失敗返回錯誤碼WSAECONNRESET。              .
[華 軟 網]
編 程論壇 6 個網友回答:   ClientAbortException: JAVA.NET.SocketException:  Connection reset by peer: socket wrITe  error的原因是由於處理http連線時,正在輸出內容時,使用者關閉了IE,會出現一個"ClientAbortException",屬於I/O處理 中出現的一個異常,應用伺服器應該會捕捉。
Connection reset by peer的原因:
經常出現的Connection reset by peer: 原因可能是多方面的,不過更常見的原因是:
①:伺服器的併發連線數超過了其承載量,伺服器會將其中一些連線Down掉;
②:客戶關掉了瀏覽器,而伺服器還在給客戶端傳送資料;
③:瀏覽器端按了Stop
很多人都說是客戶端造成的,沒有辦法控制,是個比較鬱悶的問題。            .
[華 軟 網]
編 程論壇 7 個網友回答:  
引用 6 樓 phoenixLotus 的回覆:
ClientAbortException: JAVA.NET.SocketException:  Connection reset by peer: socket wrITe  error的原因是由於處理http連線時,正在輸出內容時,使用者關閉了IE,會出現一個"ClientAbortException",屬於I/O處理 中出現的一個異常,應用伺服器應該會捕捉。 
Connection reset by peer的原因: 
經常出現的Connection reset by peer: 原因可能是多方面的,不過更常見的原因是: 
①:伺服器的併發連線數超過了其承載量,伺服器會…


都不是這些原因,就我一個人訪問那伺服器,我沒有關IE,也沒有按STOP。            .
[華 軟 網]
編 程論壇 8 個網友回答:   試下這個了 不行我也沒辦法了:
引起該問題的原因是由於此時Server端連線已經被複位,而Client依然通過該連線在接收和傳送資料,在網上搜尋了一下 該錯誤,發現該錯誤引起的原因大都是防火牆的原因。            .
[華 軟 網]
編 程論壇 9 個網友回答:   一般是有些客戶端已關閉,一些執行緒因為延遲等原因覺察不到此連線已結束,繼續等到到出錯

或是

客戶端那裡不停刷或一個訪問/重新整理沒完成前再刷,要讓這個無用的執行緒死掉


看就你一個人訪問的話,就是第一種了            .
[華 軟 網]
編 程論壇 10 個網友回答:   查詢了一下網上有人說
這個問題一般是客戶端在連線還沒有完全建立的時候就取消連線,比如使用者按了瀏覽器上面的“停止”按鈕,一般來說沒有什麼問題。但是如果頻繁出現,就表示很 多客戶端連線到Apache伺服器的響應時間太長了,可能是網路的問題或者伺服器效能問題。            .
[華 軟 網]
編 程論壇 11 個網友回答:   留個腳印。關注!            .
[華 軟 網]
編 程論壇 12 個網友回答:   我想應該不是連線中斷的問題吧。
我根本就沒有不停地去重新整理或者按停止按鈕之類的。
而且在我的機子上,無論訪問多少次,都是錯的。/

在伺服器上訪問無論多少次都是正確的。
剛有一英國的朋友也訪問了一下,他那裡也沒有錯。。            .
[華 軟 網]
編 程論壇 13 個網友回答:   一起關注吧            .
[華 軟 網]
編 程論壇 14 個網友回答:  
引用 5 樓 phoenixLotus 的回覆:
說是這原因 
存在的連線被遠端主機強制關閉。通常原因為:遠端主機上對等方應用程式突然停止執行,或遠端主機重新啟動,或遠端主機在遠端方套接字上使用了“強制”關閉 (參見setsockopt(SO_LINGER))。另外,在一個或多個操作正在進行時,如果連線因“keep-alive”活動檢測到一個失敗而中 斷,也可能導致此錯誤。此時,正在進行的操作以錯誤碼WSAENETRESET失敗返回,後續操作將失敗返回錯誤碼WSAECONNRESET。  

有可能,看了下,覺得不是程式的問題,可能是網路連接出現的問題

還有個情況說下,樓主這段程式的異常處理太簡單了啊            .
[華 軟 網]
編 程論壇 15 個網友回答:   試下這個了 不行我也沒辦法了: 
引起該問題的原因是由於此時Server端連線已經被複位,而Client依然通過該連線在接收和傳送資料,在網上搜尋了一下 該錯誤,發現該錯誤引起的原因大都是防火牆的原因。