博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android笔记--TCP Scoket(字符串收发)
阅读量:7232 次
发布时间:2019-06-29

本文共 8043 字,大约阅读时间需要 26 分钟。

hot3.png

Tcp的连接和断开其实也就是很简短的代码,比较麻烦的就是断线检测重连等机制,如何设置的比较合理节省资源。

本代码暂时只是做简单的发送接收,并没有做比较严格的发送接收队列。

首先是断线,socket.isClosed() || !socket.isConnected()这两个socket方法都只是本地方法,如果在服务器端断开连接的话,这两个方法是检测不出来的。网上查了一下,据说是有4中方法来检测连接是否已经真正断开,方便起见我选用了sendUrgentData()方法,

socket.sendUrgentData(0);//发送1个字节的紧急数据,默认情况下,服务器端没有开启紧急数据处理,不影响正常通信

为了验证发送状态,我再每次发送消息之前都会做一次检测,如果是频繁发送数据,不建议加上这个。

接收线程是阻塞的,所以不太好时时刻刻做这检测,所以我另外加了一个心跳机制,每秒(这个时间是非常频繁的)检测一次连接是否断开,如果断开则启动重连机制。

ALog类是我自定的输出打印类,用Log替换一下即可

package com.imxiaoyu.common.impl;/** * 回调一个字符串 * Created by 她叫我小渝 on 2016/11/1. */public interface OnStringListener {    void onClick(String str);}

整个类的代码:

package com.ilink.ght.core.network.helper;import android.os.Handler;import android.os.Message;import com.imxiaoyu.common.impl.OnStringListener;import com.imxiaoyu.common.impl.OnSuccessListener;import com.imxiaoyu.common.utils.ALog;import com.imxiaoyu.common.utils.ByteUtils;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.IOException;import java.io.InputStreamReader;import java.io.OutputStream;import java.io.OutputStreamWriter;import java.io.PrintWriter;import java.net.Socket;import java.util.ArrayList;import java.util.List;/** * tcp发送接受帮助类 * Created by XiaoYu on 2017/2/22. */public class TcpHelper {    private static String content;    private static List
onStringListenerList; /** * 常量 */ private static final String HOST = "192.168.0.191"; private static final int PORT = 34952; /** * 变量 */ private static Socket socket = null; private static BufferedReader in = null; private static PrintWriter out = null; /** * TCP连接 */ public static void connTCP() { new Thread() { @Override public void run() { try { socket = new Socket(HOST, PORT); in = new BufferedReader(new InputStreamReader(socket .getInputStream())); out = new PrintWriter(new BufferedWriter(new OutputStreamWriter( socket.getOutputStream())), true); ALog.e("连接成功"); Message msg = new Message(); msg.obj = "连接成功"; mHandler.sendMessage(msg); if (checkConn()) { receiveMsg();//注册消息接收 ALog.e("连接注册消息接收"); handler.postAtTime(runnable, 1000); } else { ALog.e("服务里,TCP连接失败"); } } catch (Exception e) { e.printStackTrace(); ALog.e("TCP连接失败,尝试重连"); connTCP(); } } }.start(); startPing(); } /** * 断开连接 */ public static void disConn() { try { in.close(); out.close(); socket.close(); } catch (Exception e) { e.printStackTrace(); } } /** * 判断连接是否可用 * * @return */ public static boolean checkConn() { if (socket == null) { return false; } if (socket.isClosed() || !socket.isConnected()) { return false; } try { socket.sendUrgentData(0);//发送1个字节的紧急数据,默认情况下,服务器端没有开启紧急数据处理,不影响正常通信 return true; } catch (Exception se) { return false; } } /** * 发送消息 * * @param str * @param onSuccessListener */ public static void sendMsg(final String str, final OnSuccessListener onSuccessListener) { final Handler sendHandlde = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); if(msg.what==1){ onSuccessListener.onSuccess(); }else{ String error=msg.obj+""; onSuccessListener.onError(error); } } }; new Thread() { @Override public void run() { Message msg=new Message(); if (checkConn()) { if (!socket.isOutputShutdown()) { out.print(str); msg.what=1; } else { ALog.e("发送,断开输出通道了"); msg.what=0; } } else { msg.what=0; msg.obj="连接已断开"; ALog.e("连接已断开"); } sendHandlde.sendMessage(msg); } }.start(); } /** * 接收消息 * 当连接发生变更的时候,必须要初始化一次这个方法, */ public static void receiveMsg() { try { while (true) { if (!socket.isClosed()) { if (socket.isConnected()) { if (!socket.isInputShutdown()) { if ((content = in.readLine()) != null) { content += "\n"; ALog.e("接收到消息:" + content); Message msg = new Message(); msg.obj = content; mHandler.sendMessage(msg); } else { ALog.e("读取不到,可能连接已经断开,关闭后尝试重连"); disConn(); ALog.e("正在尝试重连"); connTCP(); break; } } else { //输入流已经关闭 ALog.e("输入流已经关闭"); } } else { //是否已连接 ALog.e("输入流,连接已经断开"); } } else { //连接已关闭 ALog.e("输入流,连接已经关闭"); } } } catch (Exception e) { e.printStackTrace(); } } public static Handler mHandler = new Handler() { public void handleMessage(Message msg) { super.handleMessage(msg); if (onStringListenerList == null) { onStringListenerList = new ArrayList<>(); } for (int i = 0; i < onStringListenerList.size(); i++) { if (onStringListenerList != null) { onStringListenerList.get(i).onClick(msg.obj + ""); } } } }; /** * 添加消息监听器 */ public static void addRceiveListener(OnStringListener onStringListener) { if (onStringListenerList == null) { onStringListenerList = new ArrayList<>(); } if (onStringListener != null) { onStringListenerList.add(onStringListener); } } /** * 移除消息监听器 * * @param onStringListener */ public static void removeRceiveListener(OnStringListener onStringListener) { if (onStringListener != null) { for (int i = onStringListenerList.size() - 1; i >= 0; i++) { if (onStringListenerList.get(i) == onStringListener) { onStringListenerList.remove(i); } } } } private static Handler handler; private static Runnable runnable; private static void startPing() { if (handler == null) { handler = new Handler(); } if (runnable == null) { runnable = new Runnable() { @Override public void run() { if (!checkConn()) { ALog.e("心跳包验证失败,已经断开,尝试重连"); Message msg = new Message(); msg.obj = "心跳包验证失败,已经断开,尝试重连"; mHandler.sendMessage(msg); disConn(); connTCP(); } else { handler.postAtTime(this, 1000); } } }; } }}

 

 

转载于:https://my.oschina.net/u/1462828/blog/843813

你可能感兴趣的文章
第三届高校SDN大赛决赛鸣锣!新华三鼎力支持SDN技术普及
查看>>
路测之外,沃尔沃还拉上了普通家庭一起参与自动驾驶项目
查看>>
2017品途NBI影响力评选四大榜单震撼揭晓
查看>>
飘刃 v0.0.10 首次发布,超快执行速度的 Vue 项目构建工具
查看>>
JS监听DOM结构变化
查看>>
浅谈URLEncoder编码算法
查看>>
Spring中Bean的后置处理器
查看>>
2017 CCS云计算渠道伙伴合作高峰论坛即将盛大开幕
查看>>
PHP调用MYSQL存储过程实例
查看>>
Spring/Spring MVC/Spring Boot实现跨域
查看>>
国内土豪真给力,特斯拉一季度中国销量同比暴涨250%
查看>>
论文解读:华盛顿大学教授Pedro Domingos技术论文:机器学习中一些有用的知识(二)...
查看>>
对Swoole、Workerman和php自带的socket的理解
查看>>
VR视频创作,想说爱你不容易
查看>>
ROS-CLI命令行源码及使用方法整理
查看>>
jdbc的数据库连接信息在属性文件中的配置(db.properties)
查看>>
VC++中的char,wchar_t,TCHAR
查看>>
java中如何将JScrollPane的垂直滚动条自动移动到最下端
查看>>
远程桌面端口修改
查看>>
性能测试工具curl-loader(linux)
查看>>