java - android 切换网络时候TCP长连接怎么重连?
巴扎黑
巴扎黑 2017-04-18 09:20:40
0
0
459

我在一个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

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

巴扎黑
巴扎黑

全員に返信 (0)
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!