我在做android pad端post接口请求时,发现了一个奇怪的问题,当我的post参数,长度小于500到600时,一切正常,数据能在1s内上传完毕。然而当我把这个字段的字符串稍微变大一点,比如到700-1000,这个请求就一直在进行,直到到达了我设置的超时时间,okhttp返回了超时异常。
java.net.SocketTimeoutException: timeout
我的超时时间一开始设置的是10s,然后发现这个问题时,我的数据是8000长度左右,我以为是网络慢,时间不够,所以我把超时时间设置为60s,但是还是不行,之后我用了500和1000的字符串,才发现了这个问题。
一个500长度字符串需要1s的话,1000长度怎么说也不会60s都不够用。后来我再把时间加长,120s时,okhttp报了一个异常为:
java.io.IOException: unexpected end of stream on http://{我服务器的接口地址}
我的okhttp请求代码就是这样,就是很正常的form表单提交,我简化了一下。
int TIMEOUT = 60;
mOkHttpClient = new OkHttpClient.Builder()
.connectTimeout(TIMEOUT, TimeUnit.SECONDS)
.readTimeout(TIMEOUT,TimeUnit.SECONDS)
.writeTimeout(TIMEOUT, TimeUnit.SECONDS)
.build();
Request.Builder builder = new Request.Builder();
builder.url(getHostname() + getUrl());
builder.post(new FormBody.Builder.add("key", "一段长的字符串").build())
Call call = mOkHttpClient.newCall(builder.build());
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
String output = response.body().string();
Log.d("okHttp response", output);
}
});
我尝试了以下操作:
1.一开始以为是服务器端限制了post长度,所以用同样的数据在postman中测试,一切正常,即使是8000字节的数据,也依然能2s内上传完成。服务器端也把tomcat的那个post-size参数设置到了100MB。
2.把okhttp升级到了最新版本,现在是4.9.1
3.加长了超时时间的设置,但也是一直在运行,一直到超时结束,报超时异常,或者设置很长的超时时间,报上述的IO异常。
以上操作均没有获得什么效果。
之后我又进行了测试。
1.发现这段程序在手机上运行,没有任何问题,4000左右长度的字符串也能很快上传完成。手机运行环境为华为P30 pro,android11,但是在之前的两个平板上,均上传超时。平板为三星galaxy tab active pro(android 11)和小米Pad4(android 8.1)。不确定是否是平板的原因,还是只是巧合。
2.之后我用Charles配置了一下抓包代理,想看看平板到底传的数据和postman有什么区别,结果神奇的发现当我用代理抓包时,程序就正常了,当我取消代理时,这个问题又复现。
有没有遇到这个问题的朋友,希望能帮助一下。