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)
問題は非常に奇妙です。例外が毎回スローされるわけではなく、時にはすべてが正常であり、プログラムが正常に動作するためです。
誰かアイデアはありますか?
「予期しないファイルの終わり」は、リモートサーバーが応答を送信せずに接続を受け入れて閉じたことを意味します。リモートシステムがビジー状態でリクエストを処理できないか、ランダムに接続を切断するネットワークバグがある可能性があります。
入手可能な情報では、何が悪いのかを言うことは不可能です。問題のサーバーにアクセスできる場合は、パケットスニッフィングツールを使用して、正確に送受信されたものを見つけ、サーバープロセスのログを調べてエラーメッセージがあるかどうかを確認できます。
この例外は、応答を期待しているが、ソケットが突然閉じられたときに発生します。
JavaのHTTPClient
が見つかりました ここ は、非常に特定の状況で、メッセージ「予期しないファイルのサーバーからの終了」を伴うSocketException
をスローします。
リクエストを作成すると、HTTPClient
は、リクエストに関連付けられたソケットに関連付けられたInputStream
を取得します。次に、次のいずれかになるまでInputStream
を繰り返しポーリングします。
InputStream
の終わりに到達すると、8文字が読み取られます番号2の場合、HTTPClient
はこのSocketException
ifをスローします。次のいずれかに該当します。
これは、サーバーが応答を送信できるようになる前にTCPソケットが閉じられたことを示します。これはさまざまな理由で発生する可能性がありますが、いくつかの可能性があります:
注:Nginxが設定を再ロードすると、 飛行中のHTTPキープアライブ接続が強制的に閉じられます (POSTでも)、このエラーが発生します。
認証ヘッダーを設定しないか、間違った資格情報を設定すると、このエラーが発生します。
私の場合、プロキシを接続に渡すだけで解決しました。 @ Andreas Panagiotidis に感謝します。
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("<YOUR.Host>", 80)));
HttpsURLConnection con = (HttpsURLConnection) url.openConnection(proxy);
Wire sharkを使用してパケットをトレースすることをお勧めします。 Ubuntuを使用している場合、sudo-aptはwiresharkを取得します。 Joniが述べたように、何が問題なのかを理解する唯一の方法は、GETリクエストとそれに関連する応答に従うことです。
ほとんどの場合、設定しているヘッダーが正しくないか、受け入れられません。
例:connection.setRequestProperty( "content-type"、 "application/json");