在我的應用程序中嘗試使用HttpClient
時,我遇到了一個相當迷惑的難題。看似隨意,HttpClient.execute(HttpRequest)
永遠不會回來!那麼......如果我使用HttpConnectionParams.setConnectionTimeout(HttpParams, int)
來設置超時,它會引發超時異常。否則我的後臺線程將永遠掛起。Android HttpClient在執行期間發送第一個數據包
我試着在陽光下的一切來彌補問題,但無濟於事。留下沒有其他選擇我採取了一個問題的數據包捕獲,並發現令人驚訝的事情! (也許並不奇怪,我不是一個真正的網絡傢伙)
成功的呼叫:
905 75.286537 192.168.20.163 192.168.20.171 TCP 74 34340 > http [SYN] Seq=0 Win=5840 Len=0 MSS=1460 SACK_PERM=1 TSval=411399 TSecr=0 WS=16
906 75.286634 192.168.20.171 192.168.20.163 TCP 74 http > 34340 [SYN, ACK] Seq=0 Ack=1 Win=8192 Len=0 MSS=1260 WS=256 SACK_PERM=1 TSval=2129684 TSecr=411399
919 78.280782 192.168.20.163 192.168.20.171 TCP 74 34340 > http [SYN] Seq=0 Win=5840 Len=0 MSS=1460 SACK_PERM=1 TSval=411783 TSecr=0 WS=16
920 78.286704 192.168.20.171 192.168.20.163 TCP 74 http > 34340 [SYN, ACK] Seq=0 Ack=1 Win=8192 Len=0 MSS=1260 WS=256 SACK_PERM=1 TSval=2129984 TSecr=411399
955 84.280710 192.168.20.163 192.168.20.171 TCP 74 34340 > http [SYN] Seq=0 Win=5840 Len=0 MSS=1460 SACK_PERM=1 TSval=412551 TSecr=0 WS=16
956 84.287958 192.168.20.171 192.168.20.163 TCP 70 http > 34340 [SYN, ACK] Seq=0 Ack=1 Win=65535 Len=0 MSS=1260 SACK_PERM=1 TSval=2130584 TSecr=411399
957 84.288332 192.168.20.163 192.168.20.171 TCP 66 34340 > http [ACK] Seq=1 Ack=1 Win=93440 Len=0 TSval=412551 TSecr=2130584
959 84.648812 192.168.20.163 192.168.20.171 TCP 294 [TCP segment of a reassembled PDU]
960 84.649333 192.168.20.163 192.168.20.171 HTTP 411 POST /xxxxx.Service/xxxxx.asmx/GetReservations HTTP/1.1 (application/json)
961 84.649368 192.168.20.171 192.168.20.163 TCP 66 http > 34340 [ACK] Seq=1 Ack=574 Win=16630272 Len=0 TSval=2130620 TSecr=412598
962 84.656518 192.168.20.171 192.168.20.163 TCP 1314 [TCP segment of a reassembled PDU]
963 84.656560 192.168.20.171 192.168.20.163 HTTP 580 HTTP/1.1 200 OK (application/json)
964 84.657192 192.168.20.163 192.168.20.171 TCP 66 34340 > http [ACK] Seq=574 Ack=1249 Win=119808 Len=0 TSval=412599 TSecr=2130621
965 84.686906 192.168.20.163 192.168.20.171 TCP 66 34340 > http [ACK] Seq=574 Ack=1764 Win=159744 Len=0 TSval=412603 TSecr=2130621
968 85.187509 192.168.20.163 192.168.20.171 TCP 66 34340 > http [FIN, ACK] Seq=574 Ack=1764 Win=159744 Len=0 TSval=412667 TSecr=2130621
969 85.187567 192.168.20.171 192.168.20.163 TCP 66 http > 34340 [ACK] Seq=1764 Ack=575 Win=16630272 Len=0 TSval=2130674 TSecr=412667
失敗的呼叫:
2653 195.296440 192.168.20.163 192.168.20.171 TCP 74 60962 > http [SYN] Seq=0 Win=5840 Len=0 MSS=1460 SACK_PERM=1 TSval=426761 TSecr=0 WS=16
2656 195.296894 192.168.20.171 192.168.20.163 TCP 74 http > 60962 [SYN, ACK] Seq=0 Ack=1 Win=8192 Len=0 MSS=1260 WS=256 SACK_PERM=1 TSval=2141685 TSecr=426761
2658 195.297191 192.168.20.163 192.168.20.171 TCP 66 60962 > http [ACK] Seq=1 Ack=1 Win=5840 Len=0 TSval=426761 TSecr=2141685
2659 195.669276 192.168.20.163 192.168.20.171 TCP 294 [TCP segment of a reassembled PDU]
2660 195.669749 192.168.20.163 192.168.20.171 HTTP 411 POST /xxxxx.Service/xxxxx.asmx/GetReservations HTTP/1.1 (application/json)
2661 195.669783 192.168.20.171 192.168.20.163 TCP 66 http > 60962 [ACK] Seq=1 Ack=574 Win=66048 Len=0 TSval=2141722 TSecr=426809
2662 195.670095 192.168.20.163 192.168.20.171 TCP 60 60962 > http [RST] Seq=574 Win=0 Len=0
2802 215.154316 192.168.20.163 192.168.20.171 TCP 74 48450 > http [SYN] Seq=0 Win=5840 Len=0 MSS=1460 SACK_PERM=1 TSval=429303 TSecr=0 WS=16
2803 215.154397 192.168.20.171 192.168.20.163 TCP 74 http > 48450 [SYN, ACK] Seq=0 Ack=1 Win=8192 Len=0 MSS=1260 WS=256 SACK_PERM=1 TSval=2143671 TSecr=429303
2804 215.154704 192.168.20.163 192.168.20.171 TCP 60 48450 > http [RST] Seq=1 Win=0 Len=0
2807 215.716852 192.168.20.163 192.168.20.171 TCP 66 60962 > http [FIN, ACK] Seq=574 Ack=1 Win=5840 Len=0 TSval=429375 TSecr=2141685
2826 218.152321 192.168.20.163 192.168.20.171 TCP 74 48450 > http [SYN] Seq=0 Win=5840 Len=0 MSS=1460 SACK_PERM=1 TSval=429687 TSecr=0 WS=16
2827 218.152387 192.168.20.171 192.168.20.163 TCP 74 [TCP Previous segment lost] http > 48450 [SYN, ACK] Seq=821395 Ack=1 Win=8192 Len=0 MSS=1260 WS=256 SACK_PERM=1 TSval=2143970 TSecr=429687
2828 218.152669 192.168.20.163 192.168.20.171 TCP 60 48450 > http [RST] Seq=1 Win=0 Len=0
2957 224.152259 192.168.20.163 192.168.20.171 TCP 74 48450 > http [SYN] Seq=0 Win=5840 Len=0 MSS=1460 SACK_PERM=1 TSval=430455 TSecr=0 WS=16
2958 224.152379 192.168.20.171 192.168.20.163 TCP 74 [TCP Previous segment lost] http > 48450 [SYN, ACK] Seq=1936893 Ack=1 Win=8192 Len=0 MSS=1260 WS=256 SACK_PERM=1 TSval=2144570 TSecr=430455
2959 224.152722 192.168.20.163 192.168.20.171 TCP 60 48450 > http [RST] Seq=1 Win=0 Len=0
3032 230.130084 192.168.20.163 192.168.20.171 TCP 639 [TCP Retransmission] 60962 > http [FIN, PSH, ACK] Seq=1 Ack=1 Win=5840 Len=573 TSval=431220 TSecr=2141685
的古怪在行2662開始,沒有明顯的時原因,我的設備發送RST數據包到服務器?爲什麼它會這樣做?你可以看到數據包在2802〜20s後發生的連接終止(這是我的超時值)。事情是,當設備發送RST數據包HttpClient.execute
不會返回,它只是坐在那裏!
也許我錯過配置我的客戶端的東西?
private static DefaultHttpClient newClient()
{
HttpParams params = new BasicHttpParams();
ConnManagerParams.setMaxConnectionsPerRoute(params, new ConnPerRouteBean(30));
ConnManagerParams.setMaxTotalConnections(params, 100);
HttpProtocolParams.setContentCharset(params, HTTP.DEFAULT_CONTENT_CHARSET);
HttpProtocolParams.setUseExpectContinue(params, false);
HttpProtocolParams.setUserAgent(params, "XXXXX XXXXXXXXXX/1.0");
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpConnectionParams.setConnectionTimeout(params, SOCKET_OPERATION_TIMEOUT);
HttpConnectionParams.setSoTimeout(params, SOCKET_OPERATION_TIMEOUT);
HttpConnectionParams.setSocketBufferSize(params, 8192);
HttpConnectionParams.setStaleCheckingEnabled(params, true);
SchemeRegistry reg = new SchemeRegistry();
reg.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
reg.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));
ThreadSafeClientConnManager mgr = new ThreadSafeClientConnManager(params, reg);
DefaultHttpClient client = new DefaultHttpClient(mgr, params);
return client;
}
或者它可能與我如何發出請求有關?
private JSONObject performRequest(String url, JSONObject values)
throws ClientProtocolException, IOException, JSONException {
HttpPost httpPost = new HttpPost(url);
httpPost.setHeader("content-type", "application/json");
httpPost.setHeader(HTTP.CONN_DIRECTIVE,HTTP.CONN_CLOSE);
StringEntity requestEntity;
requestEntity = new StringEntity(values.toString(), HTTP.UTF_8);
httpPost.setEntity(requestEntity);
HttpResponse response;
HttpEntity responseEntity = null;
String responseString;
try {
//this is the line that never returns
response = _httpClient.execute(httpPost);
responseEntity = response.getEntity();
responseString = EntityUtils.toString(responseEntity);
} finally {
if (responseEntity != null)
responseEntity.consumeContent();
}
String d = new JSONObject(responseString).getString("d");
if (d.length() > 0)
return new JSONObject(d);
else
return new JSONObject();
}
同樣HttpClient
用於在我的應用程序的所有Web服務調用和多線程可以訪問此客戶端。我假定使用ThreadSafeClientConnManager
將提供我需要的線程安全性,但我猜可能還有其他東西我錯過了。
任何幫助非常感謝,我一直在努力解決這個問題,一直在敲着我的頭對着鍵盤。
編輯 我想我應該提到這一點,只有當我使用機器名作爲URL時,沒有如果我使用特定的IP地址。
我無法想象這是問題,因爲我看到兩個相同請求之間的不同行爲。 – FlyingStreudel
如果您看到不同的行爲,那麼根據定義,請求之間必定有差異。你能提供你正在提出的請求的例子嗎? – WindyB
該問題不在Web服務上,問題是設備終止連接請求。這從呼叫呼叫中發生不一致。 – FlyingStreudel