首页 > android 切换网络时候TCP长连接怎么重连?

android 切换网络时候TCP长连接怎么重连?

我在一个Android程序中,使用TCP连接的方式保持与服务器的长连接,这是在service里边开启一个线程进行的,向服务器发出了第一次数据之后,就用死循环来保持长久的等待服务器响应,如果超时之后抛出超时异常不作处理,程序可以正常运行,也可以正常接收服务器的返回信息,但是当我的网络出问题的时候,wifi和数据切换的时候,就会抛出异常,具体是在循环接收的时候抛出的recvfrom failed,怎么样才能在这种情况下重新连接呢?下面我贴出这个类的代码,如果有更好的办法也可以给我提下。

TCP连接的Service类

package cn.succy.jxyy.service.impl;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
import java.net.SocketException;
import java.net.SocketTimeoutException;

import org.json.JSONObject;

import cn.succy.jxyy.receiver.NetWorkChangeBroadcastReceiver;
import cn.succy.jxyy.view.LoginActivity;
import cn.succy.jxyy.view.MainActivity;
import cn.succy.jxyy.view.PopWindowActivity;
import cn.succy.jxyy.view.WelcomeActivity;
import android.app.Activity;
import android.app.Service;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.IBinder;

/**
 * 
 * @Description:该类是一个tcp连接的服务类,开启一个后台服务, 创建tcp连接,旨在进行和服务器之间的长连接,用于单点登录和消息 推送。
 * @Title: TcpConnService
 * @author Succy
 * @Company www.succy.cn
 * @date 2016年5月20日下午11:07:44
 */
public class TcpConnService extends Service {

    public static Socket client;
    private SharedPreferences sharedPreferences;
    private Intent intent;
    private Editor editor;
    private PrintStream out;
    private BufferedReader buf;

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    // 构建service
    @Override
    public void onCreate() {
        super.onCreate();

        // atm =
        System.out.println("进入到服务创建");
        sharedPreferences = this.getSharedPreferences("login",
                Activity.MODE_PRIVATE);
        editor = sharedPreferences.edit();
        new Thread() {
            public void run() {
                try {
                    client = new Socket("121.42.34.63", 8889);
                    session();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            };
        }.start();
    }

    // 销毁service
    @Override
    public void onDestroy() {
        super.onDestroy();
        System.out.println("onDestroy()");
        try {
            if (buf != null) {
                buf.close();
            }
            if (out != null) {
                out.close();
            }
            if (client != null) {
                client.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 向服务器发起会话
    public void session() throws Exception {
        String sessionId = sharedPreferences.getString("sessionId", "");
        String telNum = sharedPreferences.getString("telNum", "");
        System.out.println("service preferences session id " + sessionId);
        client.setSoTimeout(10000);

        // 获取Socket的输出流,用来发送数据到服务端
        out = new PrintStream(client.getOutputStream());

        JSONObject params = new JSONObject();
        params.put("app_session_id", sessionId);
        params.put("tel_number", telNum);

        // 发送数据到服务端
        out.println(params.toString());

        System.out.println("进入会话状态!");
        System.out.println("arg:" + params.toString());

        boolean flag = true;
        while (flag) {
            System.out.println("test -->");
            System.out.println("in while socket isConnect-->"
                    + client.isConnected());
            try {
                // 获取Socket的输入流,用来接收从服务端发送过来的数据
                buf = new BufferedReader(new InputStreamReader(
                        client.getInputStream(), "UTF-8"));
                // 从服务器端接收数据有个时间限制(系统自设,也可以自己设置),超过了这个时间,便会抛出该异常
                String echo = buf.readLine();//**recvfrom failed异常是在这里抛出的**//
                // echo = URLDecoder.decode(echo, "UTF-8");
                System.out.println(echo);
                JSONObject result = new JSONObject(echo);
                int code = result.getInt("code");
                switch (code) {
                case 200:
                    intent = new Intent(getBaseContext(), MainActivity.class);
                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    getApplication().startActivity(intent);
                    if (WelcomeActivity.welAct != null) {
                        WelcomeActivity.welAct.finish();
                    }
                    if (LoginActivity.loginAct != null) {
                        LoginActivity.loginAct.finish();
                    }
                    break;

                case 800:
                    flag = false;
                    stopSelf();
                    intent = new Intent(getBaseContext(),
                            PopWindowActivity.class);
                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    getApplication().startActivity(intent);

                    editor.putBoolean("loginState", false);
                    editor.putString("sessionId", "");
                    editor.putString("telNum", "");
                    editor.commit();
                    break;
                case 801:
                    flag = false;
                    System.out.println("这是801---");
                    stopSelf();
                    intent = new Intent(getBaseContext(), LoginActivity.class);
                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    getApplication().startActivity(intent);

                    if (MainActivity.mainAct != null) {
                        MainActivity.mainAct.finish();
                    }
                    break;
                default:
                    flag = false;
                    stopSelf();
                    intent = new Intent(getBaseContext(), LoginActivity.class);
                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    getApplication().startActivity(intent);

                    editor.putBoolean("loginState", false);
                    editor.putString("sessionId", "");
                    editor.putString("telNum", "");
                    editor.commit();
                    break;
                }
            } catch (SocketTimeoutException e) {
                System.out.println("Time out, No response");
            } catch (SocketException e) {
                if (NetWorkChangeBroadcastReceiver.hasNetWork) {
                    System.out.println("网络连接正常");
                } else {
                    System.out.println("网络连接异常");
                }
                System.out.println("套接口异常-->" + e.getMessage());
                System.out.println("isClose-->" + client.isClosed()
                        + " isConnect-->" + client.isConnected());
                client.close();
                e.printStackTrace();
                // break;
            }
        }
    }

}

以下是抛出的异常

java.net.SocketException: recvfrom failed: ETIMEDOUT (Connection timed out)
at libcore.io.IoBridge.maybeThrowAfterRecvfrom(IoBridge.java:634)
at libcore.io.IoBridge.recvfrom(IoBridge.java:596)
at java.net.PlainSocketImpl.read(PlainSocketImpl.java:497)
at java.net.PlainSocketImpl.access$000(PlainSocketImpl.java:43)
at java.net.PlainSocketImpl$PlainSocketInputStream.read(PlainSocketImpl.java:243)
at java.io.InputStreamReader.read(InputStreamReader.java:231)
at java.io.BufferedReader.readLine(BufferedReader.java:397)
at cn.succy.jxyy.service.impl.TcpConnService.session(TcpConnService.java:119)
at cn.succy.jxyy.service.impl.TcpConnService$1.run(TcpConnService.java:61)
Caused by: android.system.ErrnoException: recvfrom failed: ETIMEDOUT (Connection timed out)
at libcore.io.Posix.recvfromBytes(Native Method)
at libcore.io.Posix.recvfrom(Posix.java:185)
at libcore.io.BlockGuardOs.recvfrom(BlockGuardOs.java:250)
at libcore.io.IoBridge.recvfrom(IoBridge.java:593)
... 8 more

这个我已经弄了几天了,也还是没有解决,在这求各位大神指点迷津,感激不尽!

【热门文章】
【热门文章】