android客户端TCP传输数据、重连、心跳检测
来源:互联网 发布:mac usb是2.0还是3.0 编辑:程序博客网 时间:2024/06/06 16:30
1.Tcp连接、发送数据、接收数据工具类
public class TcpUtil { public static final int PORT = 9000; public static final String HOST = "192.168.2.127"; public static Socket socket; private static TcpUtil utils = null; public static TcpUtil getInstance(Context context) { if (utils == null) { synchronized (TcpUtil.class) { if (utils == null) { utils = new TcpUtil(context); } } } return utils; } PreferencesUtil p; public TcpUtil(Context context) { socket = new Socket(); SocketAddress socAddress = new InetSocketAddress(HOST, PORT); try { socket.connect(socAddress, 3000); Log.i("ds>>>", " 連接成功"); } catch (IOException e) { e.printStackTrace(); if (p == null) p = new PreferencesUtil(context, "stats"); p.setState(false); utils = null; Log.i("ds>>>", " 連接失败"); } } /** * 设置超时时间,该方法必须在bind方法之后使用. */ public void setSoTimeout(final int timeout) throws Exception { socket.setSoTimeout(timeout); } /** * 获得超时时间. */ public int getSoTimeout() throws Exception { return socket.getSoTimeout(); } public final Socket getSocket() { return socket; } /** * 向指定的服务端发送数据信息. */ public final OutputStream send(final byte[] data) throws IOException { OutputStream o = null; if (socket != null) o = socket.getOutputStream(); if (data != null) o.write(data); return o; } /** * 接收从指定的服务端发回的数据. */ public final boolean receive() throws Exception { try { InputStream inputStream = socket.getInputStream(); byte[] b = new byte[1024]; while (true) { int length = inputStream.read(b); String Msg = new String(b,0, length,"UTF-8"); if (!StringUtil.isEmpty(Msg)) return true; } } catch (Exception ex) { ex.printStackTrace(); } return false; } /** * 关闭tcp连接. */ public void close() { try { socket.close(); } catch (Exception ex) { ex.printStackTrace(); } } public void setNull() { if (utils != null) utils = null; }
使用:
由于android中耗时操作(比如网络操作)不能在主线程进行,因此需要开辟新的线程单独做耗时的操作。
new Thread(r).start();
Runnable r = new Runnable() { @Override public void run() { try { TcpUtil instance = TcpUtil.getInstance(MessageActivity.this); if (instance != null) { instance.send(b5); if (instance.receive()) {//客户端发送数据出去后,服务端需返回信息告诉客户端是否接收成功 runOnUiThread(new Runnable() { @Override public void run() { Toast.makeText(MessageActivity.this, "接收成功", Toast.LENGTH_SHORT).show(); } }); instance.close(); returnMsg(); finish(); }else { runOnUiThread(new Runnable() { @Override public void run() { Toast.makeText(MessageActivity.this, "接收失敗", Toast.LENGTH_SHORT).show(); } }); } } } catch (IOException e) { if (p == null) p = new PreferencesUtil(MessageActivity.this, "stats"); p.setState(false); e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } };
权限相关:<!--允许应用程序改变网络状态--> <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/> <!--允许应用程序改变WIFI连接状态--> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/> <!--允许应用程序访问有关的网络信息--> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <!--允许应用程序访问WIFI网卡的网络信息--> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> <!--允许应用程序完全使用网络--> <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.WAKE_LOCK" />
2.Tcp重传、心跳检测
在项目里,我的需求是,a:当软件一运行,就需要告诉服务器,我上线了。b:客户端需求间隔10s发送在线请求判断是否客户端在线。
做法:使用服务!!!每次软件一运行就打开服务,软件关闭关闭服务。
Intent i = new Intent(MainActivity.this, WorkService.class); i.setAction("android.intent.action.RESPOND_VIA_MESSAGE"); startService(i);
<service android:name=".service.WorkService" android:label="SmartCamService" android:enabled="true" > <intent-filter> <action android:name="android.intent.action.RESPOND_VIA_MESSAGE" /> </intent-filter> </service>
public class WorkService extends Service { private byte[] b5; private PreferencesUtil p; private int fflag;//fflag=1代表软件第一次打开的请求,fflag=2代表心跳检测。 @Nullable @Override public IBinder onBind(Intent intent) { return null; } @Override public void onCreate() { super.onCreate(); if (p == null) p = new PreferencesUtil(getApplication(), "stats"); fflag=1; Timer timer = new Timer(); timer.schedule(new MyTimerTask(), 0, 10000); } @Override public boolean onUnbind(Intent intent) { return super.onUnbind(intent); } class MyTimerTask extends TimerTask { public MyTimerTask() { } @Override public void run() { runResult(); } } private void runResult() { getByteData(fflag); new Thread(new Runnable() { @Override public void run() { TcpUtil t = TcpUtil.getInstance(getApplication()); if (p == null) p = new PreferencesUtil(getApplication(), "stats"); try { t.send(b5); if (t.receive()) { p.setState(true); fflag = 2;//只有在成功返回数据时候,才代表是心跳检测步骤了。 } } catch (Exception e) { p.setState(false); fflag=1;//只有一连接失败,fflag就等于1,回到最初软件打开的状态。 t.setNull();//此时需要有置空操作,这样每次连接失败的时候才能重连。 e.printStackTrace(); } } }).start(); } private void getByteData(int flag) {//1代表第一次2.代表心跳 JSONObject jsonObject = new JSONObject(); byte[] ECOMMANDTYPE = null; try { jsonObject.put("Sn", android.os.Build.SERIAL); if (flag == 1) jsonObject.put("Name", "");//flag=1或2时候发送给服务器的内容不同 byte[] len = DataUtil.intToBytes(jsonObject.toString().getBytes().length); byte[] EMESSAGETYPE = DataUtil.intToBytes(2); if (flag == 1) ECOMMANDTYPE = DataUtil.intToBytes(0x0100); else ECOMMANDTYPE = DataUtil.intToBytes(0x0000);//心跳 byte[] Info = jsonObject.toString().getBytes(); byte[] b1 = DataUtil.byteMerger(MyValue.byte_TS_HEAD, len); byte[] b2 = DataUtil.byteMerger(EMESSAGETYPE, ECOMMANDTYPE); byte[] b3 = DataUtil.byteMerger(Info, MyValue.byte_TS_TAIL); byte[] b4 = DataUtil.byteMerger(b1, b2); b5 = DataUtil.byteMerger(b4, b3); } catch (JSONException e) { e.printStackTrace(); } }}
public class DataUtil { public static byte[] byteMerger(byte[] byte_1, byte[] byte_2){ byte[] byte_3 = new byte[byte_1.length+byte_2.length]; System.arraycopy(byte_1, 0, byte_3, 0, byte_1.length); System.arraycopy(byte_2, 0, byte_3, byte_1.length, byte_2.length); return byte_3; } public static byte[] intToBytes( int value ) { byte[] src = new byte[4]; src[3] = (byte) ((value>>24) & 0xFF); src[2] = (byte) ((value>>16) & 0xFF); src[1] = (byte) ((value>>8) & 0xFF); src[0] = (byte) (value & 0xFF); return src; }}
阅读全文
1 0
- android客户端TCP传输数据、重连、心跳检测
- Netty 4.0 实现心跳检测和断线重连
- Netty 4.0 实现心跳检测和断线重连
- TCP/IP 长连接 心跳 重连 重发 线程
- websocke心跳重连
- Android Socket连接(模拟心跳包,断线重连,发送数据等)
- tcp连接检测及重连
- Netty心跳和重连
- TCP服务端-客户端(客户端具有重连功能)
- TCP,socket 心跳检测
- 基于netty的网络聊天室(二)——心跳检测及断线重连
- 基于netty的网络聊天室(二)——心跳检测及断线重连
- 【c#源码】基于TCP通信的客户端断线重连
- Netty4 Tcp长连接、断开重连、心跳监测、Msgpack编码解码
- 一秒学会安卓tcp基于netty4.x心跳,断线重连,状态监听
- 浅谈IM软件客户端的断线重连、心跳和长在线
- TCP自动重连
- android TCP/IP传输(客户端)
- DNS over TLS:保护网络浏览安全
- linux命令——df
- [喵咪Liunx(5)集群管理利器pssh
- TCP长连接与短连接的区别
- learn opencv-神经网络:初学者视图
- android客户端TCP传输数据、重连、心跳检测
- 爬坑日记--------vue的权限控制(vuex)
- [喵咪Liunx(6)]Nginx日志分析工具goaccess
- Spring 出现Could not resolve placeholder问题的解决方法
- 迅为4418开发板TF卡烧写Android和Qt内容分享
- jquery实现二级导航下拉菜单效果
- java web基本流程
- 由struts衍生出的Velocity技术
- 2017年第3届上海国际零售业设计与设备展会刊(参展商名录)