从3g切换到wifi后,与服务器的连接为所有应用程序返回EHOSTUNREACH

时间:2013-05-21 15:20:41

标签: android tcp wifi galaxy

我已经构建了一个小型的android测试tcp客户端,它连接到Ip,发送 hello world ,并定期发送日期时间。

为了测试这个,我使用 netcat 作为服务器,方式如下:

nc -l 5000

客户端通过套接字连接到服务器,日期时间正确地显示在 netcat 屏幕上,使用wifi或3g网络。

如果以3g启动应用程序并让应用程序在一小段时间(一秒间隔)内发送日期时间并更改为wifi网络,我将获得 EHOSTUNREACH 以获取与我的服务器IP的所有连接,由tcp客户端应用程序或任何其他应用程序在任何端口(例如浏览器)上制作,但仅在发生错误的wifi网络中。

如果我更改为3g或另一个wifi网络没有返回错误,但如果我回到该wifi网络,我会再次收到错误。并保持这种方式,直到我重新启动手机或让Android独立约30分钟。

仅在某些网络中发生这种情况,并且只有在数据发送周期很短的情况下,每次更改时才会发生1秒间隔或更短时间,如果周期为5秒,则每4-5次更改发生1次。

客户端代码如下

    private void test(){
    AsyncTask<Void,Void,Void> task = new AsyncTask<Void,Void,Void>(){

        @Override
        protected Void doInBackground(Void... params) {
            int iterador = 0;
            try {
                if(mSocket!= null && !mSocket.isClosed()){
                    mSocket.close();
                }

                if(waitNetworkConnection(getApplicationContext(), 3))
                {

                    mSocket = new Socket(Proxy.NO_PROXY);
                    mSocket.setReuseAddress(false);
                    mSocket.setSoTimeout(100);
                    mSocket.setTcpNoDelay(false);//false seems to work better
                    mSocket.setKeepAlive(false);
                    mSocket.setSoLinger(false, 5);
                    mSocket.setOOBInline(false);



                    mSocket.connect(new InetSocketAddress("xxx.xxx.xxx", 5000));



                    PrintWriter out;
                    OutputStream stream = mSocket.getOutputStream();
                    OutputStreamWriter outputStream = new OutputStreamWriter(stream);
                    BufferedWriter buff = new BufferedWriter(outputStream);
                    out = new PrintWriter(buff, true);  
                    out.println("hello");
                    out.println("world");

                    Date date;
                    do {
                        try {
                            Thread.sleep(200);

                            if(out.checkError() || mSocket.isOutputShutdown())
                            {
                                System.out.println("some error has happed let's close the socket");


                                try {
                                    mSocket.shutdownOutput();
                                }
                                catch(Exception e){}
                                try {
                                    mSocket.shutdownInput();
                                }
                                catch(Exception e){}
                                try {
                                    mSocket.close();
                                }
                                catch(Exception e){}

                            }else
                            {
                                if(waitNetworkConnection(getApplicationContext(), 3))
                                {
                                    if(iterador > 10*5)
                                    {
                                        Thread.sleep(5000);
                                    }
                                    date = new Date();
                                    String msg = "["+String.valueOf(iterador)+"] keeping connection at "+date.toString();
                                    System.out.println("Sending: " + msg);
                                    out.println(msg);

                                    out.flush();
                                    iterador++;
                                }
                            }
                        } catch (InterruptedException e) {

                            e.printStackTrace();
                        }

                    }while(!mSocket.isClosed());

                }
            }
            catch(Exception se){
                String err = se.getMessage();
                if(null == err){
                    err = se.toString();
                }
                System.out.println(err);
            }
            System.out.println("Socket closed");

            new Handler(getMainLooper()).postDelayed(new Runnable() {

                @Override
                public void run() {

                    test();
                }
            }, 5000);

            return null;
        }

    };
    task.execute();
}
public static boolean waitNetworkConnection(Context context, int retries) throws InterruptedException {
    ConnectivityManager cm = (ConnectivityManager) 
            context.getSystemService(Context.CONNECTIVITY_SERVICE);

    NetworkInfo ni = getNetworkToTest(cm);

    if (ni == null || !ni.isConnected()) {
        // sleep a short while to allow system to switch connecting networks.
        Thread.sleep(1000);
        int counter = 0;
        while (counter < retries && (ni == null || (ni.isAvailable() && 
                !ni.isConnected()))) {
            Thread.sleep(500);
            ni = getNetworkToTest(cm);
            counter++;
        }
    }

    return (cm.getActiveNetworkInfo() != null && 
            cm.getActiveNetworkInfo().isConnected());
}

private static NetworkInfo getNetworkToTest(ConnectivityManager cm) {
    NetworkInfo[] nis = cm.getAllNetworkInfo();
    NetworkInfo ni = cm.getActiveNetworkInfo();

    for (int i = 0; i < nis.length; i++) {
        if (nis[i].getType() == ConnectivityManager.TYPE_WIFI && nis[i].isAvailable()) {
            ni = nis[i];
            return(ni);
        }
    }
    return(ni);
}

测试在Samsumg galaxy S3(android 4.1.2)和Samsung Galaxy S2(android 4.1.2)上进行的测试。 路由器发生这种情况的一个网络是D-link 802.11g / 2.4GHz

0 个答案:

没有答案