簡體   English   中英

Java簡單代碼:java.net.SocketException:來自服務器的文件意外結束

[英]Java simple code: java.net.SocketException: Unexpected end of file from server

我用Java寫了一些簡單的代碼,該方法應該連接到網站並返回BufferedReader。

private BufferedReader getConnection(String url_a) {
        URL url;
        try {
            System.out.println("getting connection");
            url = new URL(url_a);
            HttpURLConnection urlConnection = (HttpURLConnection) 
                     url.openConnection();
            urlConnection.addRequestProperty("User-Agent",
                    "Mozilla/5.0 (X11; U; Linux i586; en-US; rv:1.7.3) Gecko/20040924"
                     + "Epiphany/1.4.4 (Ubuntu)");
            inStream = new InputStreamReader(urlConnection.getInputStream());
            return new BufferedReader(inStream);
        } catch (Exception ex) {
            Logger.getLogger(Reader.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;

}

當我在我的 PC 上使用它時,它工作正常,但是當我將 .jar 文件放在服務器上時,我收到此錯誤:

java.net.SocketException: Unexpected end of file from server
at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:718)
at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:579)
at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:715)
at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:579)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1322)
at dataconverter.Reader.getConnection(Reader.java.260)

問題很奇怪,因為不是每次都拋出異常,有時一切正常,程序運行正常。

有人有什么想法嗎?

“文件意外結束”意味着遠程服務器接受並關閉了連接而沒有發送響應。 遠程系統可能太忙而無法處理請求,或者存在隨機斷開連接的網絡錯誤。

服務器中也可能存在錯誤:請求中的某些內容導致內部錯誤,並且服務器只是關閉連接而不是像應有的那樣發送 HTTP 錯誤響應。 一些人認為這是由於請求中缺少標頭或無效標頭值引起的。

有了可用的信息,就不可能說出出了什么問題。 如果您有權訪問相關服務器,則可以使用數據包嗅探工具來查找發送和接收的確切內容,並查看服務器進程的日志以查看是否有任何錯誤消息。

概括

當您期待響應時會遇到此異常,但套接字已突然關閉。

詳細說明

Java 的HTTPClient (在此處找到)在非常特定的情況下拋出帶有消息“來自服務器的文件意外結束”的SocketException

發出請求后, HTTPClient獲取一個與請求關聯的套接字綁定的InputStream 然后它反復輪詢InputStream直到它:

  1. 查找字符串“HTTP/1”。
  2. 在讀取 8 個字符之前到達InputStream的末尾
  3. 查找“HTTP/1”以外的字符串。

在第 2 種情況下,如果以下任何一項為真, HTTPClient將拋出此SocketException

  • HTTP 方法是CONNECT
  • HTTP 方法為POST且客戶端設置為流模式

為什么會發生這種情況

這表明 TCP 套接字在服務器能夠發送響應之前已關閉。 這可能由於多種原因而發生,但一些可能性是:

  • 網絡連接丟失
  • 服務器決定關閉連接
  • 客戶端和服務器(nginx、路由器等)之間的某些東西終止了請求

注意:當 Nginx 重新加載其配置時,它會強制關閉任何正在進行的 HTTP Keep-Alive 連接(甚至是 POST),從而導致這個確切的錯誤。

當我未設置身份驗證標頭或設置錯誤的憑據時,我確實收到此錯誤。

我建議使用鋼絲鯊來追蹤數據包。 如果您使用的是 Ubuntu,請使用 sudo-apt get wireshark。 正如 Joni 所說,找出問題所在的唯一方法是跟蹤 GET 請求及其相關響應。

http://www.wireshark.org/download.html

就我而言,只需將代理傳遞給連接即可解決。 感謝@Andreas Panagiotidis

Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("<YOUR.HOST>", 80)));
HttpsURLConnection con = (HttpsURLConnection) url.openConnection(proxy);

您設置的標題很可能不正確或不可接受。

例子:

connnection.setRequestProperty("content-type", "application/json");

在我的情況下 url 包含錯誤的字符,如空格。 總體記錄您的網址,在某些情況下使用瀏覽器。

Tuve el mismo problema porque mi respuesta tardaba... y cerré mi servidor donde me salió el mismo error。 El problema era porque en mi URL enviaba un req.parmas con "" espacios: por ejemlo: id="Dispositivo FDM" donde el problema era el espacio de la cadena controle ese "espacio" y volvio a funcionar Correctamente!!! 薩盧多斯

我也遇到了這個例外。 我的錯誤代碼如下

        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
    connection.setRequestMethod(requestMethod);
        connection.setRequestProperty("Content-type", "JSON");

我發現“Content-type”不應​​該是“JSON”,錯了! 我通過將此行更新到下面解決了這個異常

        connection.setRequestProperty("Content-type", "application/json");

你可以檢查你的“內容類型”

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM