HttpURLConnection中的SocketTimeoutException在getResponseCode中随机出现

时间:2016-01-10 09:45:40

标签: android httpurlconnection intentservice

我在con.getResponseCode()

中遇到以下错误
java.net.SocketTimeoutException: failed to connect to example.com (port 80) after 3000ms
at libcore.io.IoBridge.connectErrno(IoBridge.java:223)
at libcore.io.IoBridge.connect(IoBridge.java:127)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:475)
at java.net.Socket.connect(Socket.java:861)
at com.android.okhttp.internal.Platform.connectSocket(Platform.java:152)
at com.android.okhttp.Connection.connect(Connection.java:101)
at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:294)
at com.android.okhttp.internal.http.HttpEngine.sendSocketRequest(HttpEngine.java:255)
at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:206)
at com.android.okhttp.internal.http.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:345)
at com.android.okhttp.internal.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:296)
at com.android.okhttp.internal.http.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:503)

第一次调用它时效果很好。 但它停止工作后它可能会在一段时间后随机开始工作。

public class HTTPLoader {
    public static String loadContentFromURLGET(String urlString,List<String[]> getVars,Context context){
        int retry = 0;
        HttpURLConnection con=null;
        BufferedReader in = null;
        StringBuffer response=null;
        if (!isConnectingToInternet(context)){
            return "{'error':'No Internet connection!'}";
        }
        while (retry++<=RETRY_CNT) {
            try {
                String urlParameters = "";
                for (String[] var : getVars) {
                    urlParameters += var[0] + "=" + URLEncoder.encode(var[1], "UTF-8") + "&";
                }
                if (urlParameters.length() > 1) {
                    urlParameters = urlParameters.substring(0, urlParameters.length() - 1);
                }
                if (urlString.charAt(urlString.length() - 1) != '?') {
                    urlString += "&";
                }
                URL url = new URL(urlString + urlParameters);
                con = (HttpURLConnection) url.openConnection();
                con.setConnectTimeout(3000);
                con.setRequestMethod("GET");
                con.setRequestProperty("User-Agent", USER_AGENT);
                con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
                con.setDoInput(true);
                con.setDoOutput(true);
                int responseCode = con.getResponseCode();
                in = new BufferedReader(
                        new InputStreamReader(con.getInputStream()));
                String inputLine;
                response = new StringBuffer();

                while ((inputLine = in.readLine()) != null) {
                    response.append(inputLine);
                }
                retry = RETRY_CNT+1;
                break;
            } catch (IOException e) {
                e.printStackTrace();
                Log.e(TAG, e.getMessage());
            }finally {
                if (in!=null){
                    try {
                        in.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (con!=null) {
                    con.disconnect();
                }
                in = null;
                con = null;
            }
        }
        if (response!=null)
            return new String(response);
        return "{'error':'No Internet connection!'}";
    }
}

从IntentService调用此loadContentFromURLGET

public class ChatUtil extends IntentService{
    protected String loadAllChats(String date){
            String response = "";
            try {
                SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
                String email = sharedPreferences.getString(QuickstartPreferences.EMAIL, "");

            List<String[]> postVars = new ArrayList<>();
            postVars.add(new String[]{"getconversation", "yes"});
            postVars.add(new String[]{"user_id", email});
            postVars.add(new String[]{"last_date", date});
            String urlString = getString(R.string.get_conversation_url);
            response = HTTPLoader.loadContentFromURLGET(urlString, postVars,getApplicationContext());
            Log.i(TAG, response.toString());
            JSONObject jsonObject = new JSONObject(response);
            if (jsonObject.has("error")) {
                //Toast.makeText(getApplicationContext(), jsonObject.getString("error"), Toast.LENGTH_SHORT).show();
                return jsonObject.getString("error");
            }
        }catch (JSONException e) {
        }
    }
protected void onHandleIntent(Intent intent) {
    String task = intent.getStringExtra(QuickstartPreferences.CURRENT_TASK);
    Intent nintent;
    String date = "";
String[] arr3 = new NewsDBUtil(getApplicationContext()).getLastChatEntry(null);
            if (arr3!=null)
                date = arr3[1];
            loadAllChats(date);
            nintent = new Intent(QuickstartPreferences.LOADING_ALL_CHAT);
            LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(nintent);
           }
}

尝试在finally块中关闭和断开流。 但没有成功。

2 个答案:

答案 0 :(得分:0)

你可以把con.getResponseCode();放在try ... catch块之间,如果它抛出SocketTimeoutException异常再试一次,但要确保你延长你的超时

if (responseCode != 200) {

           ....
           ...

    } catch (final java.net.SocketTimeoutException e) {
        // connection timed out...let's try again                
    } 

可能有帮助

答案 1 :(得分:0)

没有特定ContentLength来自setFixedLengthStreamingMode

我发现有些设备生成了不完整的http请求

因为服务器必须等到服务器或客户端超时

您可以使用wireshark来分析问题