Android OkHttp HTTP 失败:java.io.IOException:流意外结束

问题描述 投票:0回答:3

SpringBoot服务器

监听本地主机:30000

Android 客户端(Android Studio 模拟器 Nexus 5X API 30)

1.使用okhttp 4.10.0-RC1、改造2.9.0

2.发送如下post请求

request

--> POST http://10.0.2.2:30000/user/login
 Content-Type: application/json; charset=UTF-8
 Content-Length: 45
{"account":"135******46","password":"123456"}
--> END POST (45-byte body)

3.请求内容如下

request content

4.但回复是空的。!!!并且Springboot日志中没有任何反应。

response

5.因为响应为空,OKHTTP 抛出 EOFException。

http EOFException
我尝试了stackover中有关此异常的所有方法,但它们不起作用。
比如添加 Header("Connection", "close") ("Transfer-Encoding": "identity")

I/okhttp.OkHttpClient: <-- HTTP FAILED: java.io.IOException: unexpected end of stream on http://10.0.2.2:30000/...
java.io.IOException: unexpected end of stream on http://10.0.2.2:30000/...
at okhttp3.internal.http1.Http1ExchangeCodec.readResponseHeaders(Http1ExchangeCodec.kt:204)
at okhttp3.internal.connection.Exchange.readResponseHeaders(Exchange.kt:110)
at okhttp3.internal.http.CallServerInterceptor.intercept(CallServerInterceptor.kt:93)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
at com.lijiahao.sharechargingpile2.network.interceptor.TokenHeaderInterceptor.intercept(TokenHeaderInterceptor.kt:26)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
at com.android.tools.profiler.agent.okhttp.OkHttp3Interceptor.intercept(OkHttp3Interceptor.java:57)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.kt:34)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.kt:95)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.kt:83)
2at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.kt:76)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
at okhttp3.logging.HttpLoggingInterceptor.intercept(HttpLoggingInterceptor.kt:219)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
at okhttp3.internal.connection.RealCall.getResponseWithInterceptorChain$okhttp(RealCall.kt:201)
at okhttp3.internal.connection.RealCall$AsyncCall.run(RealCall.kt:517)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:923)
Caused by: java.io.EOFException: \n not found: limit=0 content=…
at okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.kt:332)
at okhttp3.internal.http1.HeadersReader.readLine(HeadersReader.kt:29)
at okhttp3.internal.http1.Http1ExchangeCodec.readResponseHeaders(Http1ExchangeCodec.kt:180)

6.我关闭了springboot服务器,问题还是一样

7.我可以在模拟器中使用 adb shell 成功 ping 10.0.2.2

adb shell ping

adb shell
generic_x86_64:/ $ ping 10.0.2.2
PING 10.0.2.2 (10.0.2.2) 56(84) bytes of data.
64 bytes from 10.0.2.2: icmp_seq=1 ttl=255 time=4.25 ms
64 bytes from 10.0.2.2: icmp_seq=2 ttl=255 time=0.745 ms
64 bytes from 10.0.2.2: icmp_seq=3 ttl=255 time=0.630 ms
64 bytes from 10.0.2.2: icmp_seq=4 ttl=255 time=0.922 ms
64 bytes from 10.0.2.2: icmp_seq=5 ttl=255 time=0.756 ms
64 bytes from 10.0.2.2: icmp_seq=6 ttl=255 time=0.826 ms
64 bytes from 10.0.2.2: icmp_seq=7 ttl=255 time=0.618 ms

8.当我在真机中运行我的应用程序时。将 10.0.2.2 更改为我的 PC IP。可以成功得到响应。除了 Host 之外,请求内容相同。

run success in real machine

邮差

发送相同的post请求,并获得响应成功

问题

Android Client 和 SpringBoot Server 好像都没有问题
唯一的问题是模拟器和 PC 本地主机之间的连接。
不知道为什么我的android studio模拟器无法访问localhost springboot服务器?

android android-emulator localhost okhttp
3个回答
2
投票

您可以尝试此修复:

OkHttpClient client = new OkHttpClient.Builder()
    .retryOnConnectionFailure(true)
    .build();

0
投票

如果在真实设备上出现此错误,那么您可以尝试以下操作:

val httpInterceptor = HttpLoggingInterceptor()
httpInterceptor.level = HttpLoggingInterceptor.Level.BODY
okBuilder.addInterceptor(httpInterceptor)

0
投票

在我的例子中,我开始在 HTTP 请求期间更改的范围内的协程中进行改造,从而取消协程。

因此,请检查您是否在可能更改的范围内调用了改造。

© www.soinside.com 2019 - 2024. All rights reserved.