web-dev-qa-db-ja.com

Java単純なコード:Java.net.SocketException:サーバーからの予期しないファイルの終わり

Javaで簡単なコードをいくつか書きました。メソッドはWebサイトに接続し、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)

問題は非常に奇妙です。例外が毎回スローされるわけではなく、時にはすべてが正常であり、プログラムが正常に動作するためです。

誰かアイデアはありますか?

30

「予期しないファイルの終わり」は、リモートサーバーが応答を送信せずに接続を受け入れて閉じたことを意味します。リモートシステムがビジー状態でリクエストを処理できないか、ランダムに接続を切断するネットワークバグがある可能性があります。

入手可能な情報では、何が悪いのかを言うことは不可能です。問題のサーバーにアクセスできる場合は、パケットスニッフィングツールを使用して、正確に送受信されたものを見つけ、サーバープロセスのログを調べてエラーメッセージがあるかどうかを確認できます。

50
Joni

概要

この例外は、応答を期待しているが、ソケットが突然閉じられたときに発生します。

詳細な説明

JavaのHTTPClientが見つかりました ここ は、非常に特定の状況で、メッセージ「予期しないファイルのサーバーからの終了」を伴うSocketExceptionをスローします。

リクエストを作成すると、HTTPClientは、リクエストに関連付けられたソケットに関連付けられたInputStreamを取得します。次に、次のいずれかになるまでInputStreamを繰り返しポーリングします。

  1. 文字列「HTTP/1」を検索します。
  2. InputStreamの終わりに到達すると、8文字が読み取られます
  3. 「HTTP/1」以外の文字列を検索します。

番号2の場合、HTTPClientはこのSocketExceptionifをスローします。次のいずれかに該当します。

  • HTTPメソッドは CONNECT です
  • HTTPメソッドは POST で、クライアントはストリーミングモードに設定されます

なぜこれが起こるのか

これは、サーバーが応答を送信できるようになる前にTCPソケットが閉じられたことを示します。これはさまざまな理由で発生する可能性がありますが、いくつかの可能性があります:

  • ネットワーク接続が失われました
  • サーバーは接続を閉じることにしました
  • クライアントとサーバー(nginx、ルーターなど)の間にあるものが要求を終了しました

注:Nginxが設定を再ロードすると、 飛行中のHTTPキープアライブ接続が強制的に閉じられます (POSTでも)、このエラーが発生します。

32
Cory Klein

認証ヘッダーを設定しないか、間違った資格情報を設定すると、このエラーが発生します。

私の場合、プロキシを接続に渡すだけで解決しました。 @ Andreas Panagiotidis に感謝します。

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

Wire sharkを使用してパケットをトレースすることをお勧めします。 Ubuntuを使用している場合、sudo-aptはwiresharkを取得します。 Joniが述べたように、何が問題なのかを理解する唯一の方法は、GETリクエストとそれに関連する応答に従うことです。

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

0
SeahawksRdaBest

ほとんどの場合、設定しているヘッダーが正しくないか、受け入れられません。

例:connection.setRequestProperty( "content-type"、 "application/json");

0
Kris