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
这个我已经弄了几天了,也还是没有解决,在这求各位大神指点迷津,感激不尽!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我也遇到同样的问题,咱们实现也大致相同,请问这个问题解决了吗?