java.net.SocketException: Unexpected end of file from server
at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:769)
at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:632)
...
at com.xiang.Main.main(Main.java:26)
含義:客戶端已建立 TCP 連接,但服務端在發送完整 HTTP 響應頭前主動關閉連接(發送 FIN 包),導致客戶端讀到 EOF 而非合法 HTTP 狀態行。
proxy_read_timeout 默認 60s,長請求被中斷但不返回 504。| 步驟 | 工具/命令 | 關注點 |
|---|---|---|
| 1. 抓包 | Wireshark / tcpdump -i any -s0 port 8001 | 確認 TCP 握手、服務端是否發送 HTTP 響應頭、FIN 包發送方 |
| 2. 檢查服務端日誌 | 應用日誌、容器日誌、Nginx error.log | 異常堆疊、OOM、線程阻塞、超時配置 |
| 3. 驗證協議 | curl -v https://127.0.0.1:8001 | 是否返回正常 HTTP、證書錯誤、重定向循環 |
| 4. 客戶端加超時與重試 | HttpClient / OkHttp 設置連接/讀取超時、重試策略 | 避免單次網絡抖動導致業務失敗 |
// 使用 OkHttp 替代原生 HttpURLConnection
OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(10, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.retryOnConnectionFailure(true)
.build();
Request request = new Request.Builder().url("https://127.0.0.1:8001").build();
try (Response response = client.newCall(request).execute()) {
if (!response.isSuccessful()) throw new IOException("HTTP " + response.code());
String json = response.body().string();
System.out.println("原始數據: " + json);
}
若服務端為自研模擬接口,請確認其實現了完整的 HTTP 協議(狀態行+頭部+空行+Body),而非裸 TCP 推流。