简体   繁体   English

Android http 连接被拒绝

[英]Android http connection refused

I created an Android test program with service and activity.我创建了一个带有服务和活动的 Android 测试程序。 In activity I start sticky service.在活动中,我开始粘性服务。 Service make http requests every 10 seconds.服务每 10 秒发出一次 http 请求。 If I not exit from activity, all works fine.如果我不退出活动,一切正常。 If I exit, service works sometime, then killed by system and restarted.如果我退出,服务有时会工作,然后被系统杀死并重新启动。 After restart sometimes http requests works, sometimes gives an error message:重启后有时http请求有效,有时会给出错误信息:

09-28 14:55:18.053 31161-31184/home.xmpp W/System.err: java.net.ConnectException: failed to connect to www.ya.ru/87.250.250.242 (port 80) after 15000ms: isConnected failed: ECONNREFUSED (Connection refused)
09-28 14:55:18.053 31161-31184/home.xmpp W/System.err:     at libcore.io.IoBridge.isConnected(IoBridge.java:238)
09-28 14:55:18.053 31161-31184/home.xmpp W/System.err:     at libcore.io.IoBridge.connectErrno(IoBridge.java:171)
09-28 14:55:18.053 31161-31184/home.xmpp W/System.err:     at libcore.io.IoBridge.connect(IoBridge.java:122)
09-28 14:55:18.053 31161-31184/home.xmpp W/System.err:     at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:183)
09-28 14:55:18.053 31161-31184/home.xmpp W/System.err:     at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:456)
09-28 14:55:18.053 31161-31184/home.xmpp W/System.err:     at java.net.Socket.connect(Socket.java:882)
09-28 14:55:18.053 31161-31184/home.xmpp W/System.err:     at com.android.okhttp.internal.Platform.connectSocket(Platform.java:174)
09-28 14:55:18.053 31161-31184/home.xmpp W/System.err:     at com.android.okhttp.Connection.connect(Connection.java:152)
09-28 14:55:18.053 31161-31184/home.xmpp W/System.err:     at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:276)
09-28 14:55:18.053 31161-31184/home.xmpp W/System.err:     at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:211)
09-28 14:55:18.053 31161-31184/home.xmpp W/System.err:     at com.android.okhttp.internal.http.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:382)
09-28 14:55:18.053 31161-31184/home.xmpp W/System.err:     at com.android.okhttp.internal.http.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:106)
09-28 14:55:18.053 31161-31184/home.xmpp W/System.err:     at com.android.okhttp.internal.http.HttpURLConnectionImpl.getOutputStream(HttpURLConnectionImpl.java:217)
09-28 14:55:18.053 31161-31184/home.xmpp W/System.err:     at home.xmpp.MyService.sendPostRequest(MyService.java:160)
09-28 14:55:18.053 31161-31184/home.xmpp W/System.err:     at home.xmpp.MyService$MyTask.doInBackground(MyService.java:128)
09-28 14:55:18.053 31161-31184/home.xmpp W/System.err:     at home.xmpp.MyService$MyTask.doInBackground(MyService.java:109)
09-28 14:55:18.053 31161-31184/home.xmpp W/System.err:     at android.os.AsyncTask$2.call(AsyncTask.java:292)
09-28 14:55:18.053 31161-31184/home.xmpp W/System.err:     at java.util.concurrent.FutureTask.run(FutureTask.java:237)
09-28 14:55:18.053 31161-31184/home.xmpp W/System.err:     at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
09-28 14:55:18.053 31161-31184/home.xmpp W/System.err:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
09-28 14:55:18.053 31161-31184/home.xmpp W/System.err:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
09-28 14:55:18.053 31161-31184/home.xmpp W/System.err:     at java.lang.Thread.run(Thread.java:818)
09-28 14:55:18.053 31161-31184/home.xmpp W/System.err: Caused by: android.system.ErrnoException: isConnected failed: ECONNREFUSED (Connection refused)
09-28 14:55:18.053 31161-31184/home.xmpp W/System.err:     at libcore.io.IoBridge.isConnected(IoBridge.java:223)
09-28 14:55:18.053 31161-31184/home.xmpp W/System.err:  ... 21 more

After the appearance of this error, the following requests will also fail.出现这个错误后,下面的请求也会失败。 I tried to start service in another process, tried to start each http request in new IntentService, tried to restart service after this error, but no results.我尝试在另一个进程中启动服务,尝试在新的 IntentService 中启动每个 http 请求,在出现此错误后尝试重新启动服务,但没有结果。 If an error has occurred, then other subsequent requests will also give an error.如果发生了错误,那么其他后续请求也会报错。 Only application restart helps.只有应用程序重启有帮助。 Has anyone encountered such problem?有没有人遇到过这样的问题? How to make a stable connection?如何建立稳定的连接? I read a lot of topics, but did not find the right answer.我阅读了很多主题,但没有找到正确的答案。

MyService.java我的服务

package home.xmpp;

import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.ComponentCallbacks2;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;

import javax.net.ssl.HttpsURLConnection;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

public class MyService extends Service implements ComponentCallbacks2 {
private Boolean disconnectAppeared = false;
static MyService instance;
private Handler mHandler = new Handler();
MyTask mt;
Boolean mtruned = false;


public static MyService getInstance(){
    return instance;
}

@Override
public IBinder onBind(final Intent intent) {
    //throw new UnsupportedOperationException("Not yet implemented");
    return new LocalBinder<MyService>(this);
}

@Override
public void onCreate() {
    super.onCreate();
    instance = this;
    mHandler.postDelayed(timeUpdaterRunnable, 100);
    Log.e("MyService"," created");
}

@Override
public int onStartCommand(final Intent intent, final int flags,
                          final int startId) {
    return Service.START_STICKY;
}

@Override
public boolean onUnbind(final Intent intent) {
    return super.onUnbind(intent);
}

@Override
public void onDestroy() {
    super.onDestroy();
    Log.e("MyService"," destroyed");
    mHandler.removeCallbacks(timeUpdaterRunnable);
}

public void onTrimMemory(int level) {
    switch (level) {
        case ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL: //Release any memory that your app doesn't need to run.
            //the system will begin killing background processes. !!!
            Log.e("Memory level","4");
            break;
        default:
            break;
    }
}

private Runnable timeUpdaterRunnable = new Runnable() {
    public void run() {
        if (mtruned == false) {
            Log.e("Time", " update");
            mt = new MyTask();
            mt.execute();
            mHandler.postDelayed(this, 10000);
        } else {
            cancelTask();
        }
    }
};

private void cancelTask() {
    if (mt == null) return;
    Log.d("MyService", "cancel result: " + mt.cancel(false));
}


    class MyTask extends AsyncTask<String,Void,String> {
        @Override
        protected void onPreExecute() {
            mtruned = true;
            super.onPreExecute();
        }
        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);
            Log.e("http","updated");
            mtruned = false;
        }
        @Override
        protected String doInBackground(String... params) {
            String result = "";
            HashMap<String,String> data = new HashMap<>();
            data.put("data", "data");
                result = sendPostRequest("http://www.ya.ru", data);
            return result;
        }
        @Override
        protected void onCancelled() {
            super.onCancelled();
            mtruned = false;
        }
}

public String sendPostRequest(String requestURL,
                              HashMap<String, String> postDataParams) {
    //Creating a URL
    URL url;

    //StringBuilder object to store the message retrieved from the server
    StringBuilder sb = new StringBuilder();
    try {
        //Initializing Url
        url = new URL(requestURL);

        //Creating an httmlurl connection
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        //Configuring connection properties
        conn.setReadTimeout(15000);
        conn.setConnectTimeout(15000);
        conn.setRequestMethod("POST");
        conn.setDoInput(true);
        conn.setDoOutput(true);

        //Creating an output stream
        OutputStream os = conn.getOutputStream();

        //Writing parameters to the request
        //We are using a method getPostDataString which is defined below
        BufferedWriter writer = new BufferedWriter(
                new OutputStreamWriter(os, "UTF-8"));
        writer.write(getPostDataString(postDataParams));

        writer.flush();
        writer.close();
        os.close();
        int responseCode = conn.getResponseCode();

        if (responseCode == HttpsURLConnection.HTTP_OK) {

            BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            sb = new StringBuilder();
            String response;
            //Reading server response
            while ((response = br.readLine()) != null){
                sb.append(response);
            }
        }

    } catch (Exception e) {
        e.printStackTrace();
    }
    return sb.toString();
}

private String getPostDataString(HashMap<String, String> params) throws UnsupportedEncodingException {
    StringBuilder result = new StringBuilder();
    boolean first = true;
    for (Map.Entry<String, String> entry : params.entrySet()) {
        if (first)
            first = false;
        else
            result.append("&");

        result.append(URLEncoder.encode(entry.getKey(), "UTF-8"));
        result.append("=");
        result.append(URLEncoder.encode(entry.getValue(), "UTF-8"));
    }

    return result.toString();
}


}

Update 05.10.17 I still not find a solution. 17 年 10 月 5 日更新我仍然没有找到解决方案。 I tested this programm on Android 4.1.2.我在 Android 4.1.2 上测试了这个程序。 It works fine.它工作正常。 On Android 5.1.1 it works about 3 minutes after exiting the activity and then I receive connection refused error.在 Android 5.1.1 上,它在退出活动后大约 3 分钟工作,然后我收到连接被拒绝的错误。 When I return to activity, errors disappears.当我返回活动时,错误消失。 On Android 6.0.1 similar situation, but the error is slightly different java.net.SocketTimeoutException: failed to connect to /94.130.25.242 (port 80) after 10000ms.在 Android 6.0.1 上情况类似,但错误略有不同 java.net.SocketTimeoutException: failed to connect to /94.130.25.242 (port 80) after 10000ms。 I think that the system blocks network activity in services after a while, but never in activities (?).我认为系统会在一段时间后阻止服务中的网络活动,但不会阻止活动(?)。

Update 05.10.17 I noticed that the connection disappears not only after the restart of the service, but also after 2-3 minutes, when exiting activity. 17 年 10 月 5 日更新我注意到连接不仅在服务重启后消失,而且在 2-3 分钟后退出活动时也会消失。 When I return to activity, connections are restored.当我恢复活动时,连接恢复。 I have made a video Link Update 06.10.17 One Android specialist told me, that this problem appear only in Xiaomi phones.我做了一个视频链接更新 06.10.17 一位安卓专家告诉我,这个问题只出现在小米手机上。 MIUI rejects network connections after some minutes.几分钟后 MIUI 拒绝网络连接。 Only OkHttp helps.只有 OkHttp 有帮助。 I will try it and will make feedback here.我会尝试,并会在这里提供反馈。

A "connect failed: ECONNREFUSED (Connection refused)" most likely means that there is nothing listening on that port AND that IP address. “连接失败:ECONNREFUSED(连接被拒绝)”很可能意味着在该端口和该 IP 地址上没有侦听任何内容。 Possible explanations include:可能的解释包括:

  • the service has crashed or hasn't been started,该服务已崩溃或尚未启动,
  • your client is trying to connect using the wrong IP address or port, or您的客户端正在尝试使用错误的 IP 地址或端口进行连接,或者
  • server access is being blocked by a firewall that is "refusing" on the server/service's behalf.服务器访问被代表服务器/服务“拒绝”的防火墙阻止。 This is pretty unlikely given that normal practice (these days) is for firewalls to "blackhole" all unwanted connection attempts.鉴于正常做法(这些天)是防火墙“黑洞”所有不需要的连接尝试,因此这不太可能。

It is impossible to use long network connections in background on Xiaomi phones.小米手机无法在后台使用长网络连接。 It's MIUI blocks any network connections after some time.一段时间后,MIUI 会阻止任何网络连接。 For critical network connections, you can use Firebase Cloud Messaging, which have high priority in Android system.对于关键的网络连接,您可以使用 Firebase Cloud Messaging,它在 Android 系统中具有高优先级。 It can initiate necesary background job.它可以启动必要的后台工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM