android 心跳的分析

最近在做一个项目中用到了心跳包的机制,其实就是传统的长连接。或许有的人知道消息推送的机制,消息推送也是一种长连接 ,是将数据有服务器端推送到客户端这边从而改变传统的“拉”的请求方式。下面我来介绍一下安卓和客户端两个数据请求的方式

1、push  这个也就是有服务器推送到客户端这边  现在有第三方技术 比如极光推送。

2、pull   这种方式就是客户端向服务器发送请求数据(http请求)

接下来 我就给大家介绍 Socket  tcp心跳包的机制   虽然这块不是很难,找一些网上的资料不是很全面   这个模块参照一个朋友的功能模块  自己也受益匪浅,现在分享给大家。

一、首先服务器和客户端有一次“握手”

public void connect()

{
        LogUtil.e(TAG, "准备链接...");
        InetAddress serverAddr;
        try {
            socket = new Socket(Config.Host, Config.SockectPort);
            _connect = true;
            mReceiveThread = new ReceiveThread();
            receiveStop = false;
            mReceiveThread.start();
            LogUtil.e(TAG, "链接成功.");

} catch (Exception e) {
            LogUtil.e(TAG, "链接出错." + e.getMessage().toString());
            e.printStackTrace();
        }
    }

二、下面就要开启一个线程  去不断读取服务器那边传过来的数据  采用Thread去实现

private class ReceiveThread extends Thread {
        private byte[] buf;
        private String str = null;

@Override
        public void run() {
            while (true) {
                try {
                    // LogUtil.e(TAG, "监听中...:"+socket.isConnected());
                    if (socket!=null && socket.isConnected()) {

if (!socket.isInputShutdown()) {
                            BufferedReader inStream = new BufferedReader(
                                    new InputStreamReader(
                                            socket.getInputStream()));
                            String content = inStream.readLine();                            
                            if (content == null)
                                continue;
                            LogUtil.e(TAG, "收到信息:" + content);
                            LogUtil.e(TAG, "信息长度:"+content.length());
                            if (!content.startsWith("CMD:"))
                                continue;
                            int spacePos = content.indexOf(" ");
                            if (spacePos == -1)
                                continue;
                            String cmd = content.substring(4, spacePos);
//                            String body = StringUtil.DecodeBase64(content
//                                    .substring(spacePos));
                            String body = content.substring(spacePos).trim();
                            LogUtil.e(TAG, "收到信息(CMD):" + cmd);
                            LogUtil.e(TAG, "收到信息(BODY):" + body);

if (cmd.equals("LOGIN"))

{
                                // 登录
                                ReceiveLogin(body);
                                continue;
                            }

if (cmd.equals("KEEPLIVE")) {
                                if (!body.equals("1")) {
                                    Log.e(TAG, "心跳时检测到异常,重新登录!");
                                    socket = null;
                                    KeepAlive();
                                } else {
                                    Date now = Calendar.getInstance().getTime();
                                    lastKeepAliveOkTime = now;
                                }
                                continue;
                            }
                        }
                    } else {
                        if(socket!=null)
                            LogUtil.e(TAG, "链接状态:" + socket.isConnected());
                    }

} catch (Exception e) {
                    LogUtil.e(TAG, "监听出错:" + e.toString());
                    e.printStackTrace();
                }
            }
        }

三 、 Socket 是否断开了  断开了 需要重新去连接

public void KeepAlive()

{
        // 判断socket是否已断开,断开就重连
        if (lastKeepAliveOkTime != null) {
            LogUtil.e(
                    TAG,
                    "上次心跳成功时间:"
                            + DateTimeUtil.dateFormat(lastKeepAliveOkTime,
                                    "yyyy-MM-dd HH:mm:ss"));
            Date now = Calendar.getInstance().getTime();
            long between = (now.getTime() - lastKeepAliveOkTime.getTime());// 得到两者的毫秒数
            if (between > 60 * 1000) {
                LogUtil.e(TAG, "心跳异常超过1分钟,重新连接:");
                lastKeepAliveOkTime = null;
                socket = null;
            }

} else {
            lastKeepAliveOkTime = Calendar.getInstance().getTime();
        }

if (!checkIsAlive()) {
            LogUtil.e(TAG, "链接已断开,重新连接.");
            connect();
            if (loginPara != null)
                Login(loginPara);
        }

//此方法是检测是否连接

boolean checkIsAlive() {
        if (socket == null)
            return false;
        try {
            socket.sendUrgentData(0xFF);
        } catch (IOException e) {
            return false;
        }
        return true;

}

//然后发送数据的方法

public void sendmessage(String msg) {
        if (!checkIsAlive())
            return;
        LogUtil.e(TAG, "准备发送消息:" + msg);
        try {
            if (socket != null && socket.isConnected()) {
                if (!socket.isOutputShutdown()) {
                    PrintWriter outStream = new PrintWriter(new BufferedWriter(
                            new OutputStreamWriter(socket.getOutputStream())),
                            true);

outStream.print(msg + (char) 13 + (char) 10);
                    outStream.flush();
                }
            }
            LogUtil.e(TAG, "发送成功!");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

有什么问题欢迎大家一起讨论和学习  接下来自己准备研究手机流媒体这块  欢迎大家一起学习共同进步!

源码下载地址:http://download.csdn.net/detail/wangliang198901/6567561

[置顶] android 心跳包的分析的更多相关文章

  1. [置顶] Android开发之serviceManager分析

    Android 开发之serviceManager分析 在Android系统中用到最多的通信机制就是Binder,Binder主要由Client.Server.ServiceManager和Binde ...

  2. [置顶] Android开发笔记(成长轨迹)

    分类: 开发学习笔记2013-06-21 09:44 26043人阅读 评论(5) 收藏 Android开发笔记 1.控制台输出:called unimplemented OpenGL ES API ...

  3. [置顶] Android逆向从未如此简单

    哈,又标题党了..不过我一定竭尽所能,写一篇最亲民的入门文章. 本文仅供学习交流之用,切勿用于非法用途,读者若运用所学知识,进行非法任何商业目的或者非法牟利,一切责任由操作者自行承担,与本人无关.希望 ...

  4. [置顶] [Android源码分析]inquiry result引起的上层变化分析

    在上一篇文章中,我们详细分析了android是如何解析蓝牙反馈上来的搜索到的设备信息,本文将会继续分析这些信息到了上层之后是如何处理. 8.inquiry result引起的上层变化 我们知道inqu ...

  5. [置顶] Android开发之ProcessState和IPCThreadState类分析

    在Android中ProcessState是客户端和服务端公共的部分,作为Binder通信的基础,ProcessState是一个singleton类,每个 进程只有一个对象,这个对象负责打开Binde ...

  6. [置顶] Android安全机制分析

    Android系统是基于Linux内核开发的,因此,Android系统不仅保留和继承了Linux操作系统的安全机制,而且其系统架构的各个层次都有独特的安全特性[2] . 1. Linux内核层安全机制 ...

  7. [置顶] Android资源文件分析

    1)修改开机默认壁纸 Android开机默认资源文件为:frameworks/base/core/res/res/values/config.xml 我们找到wallpaper行: <strin ...

  8. [置顶] Android源码分析-点击事件派发机制

    转载请注明出处:http://blog.csdn.net/singwhatiwanna/article/details/17339857 概述 一直想写篇关于Android事件派发机制的文章,却一直没 ...

  9. [置顶] Android开发之Thread类分析

    在我们Linux系统中创建线程函数为:pthread_create(),在Android中我们为线程封装了一个类Thread,实际调用的还是pthread_create() 当我们想创建线程的时候,只 ...

随机推荐

  1. 网络上USB后面跟AF或AM接口的意思

    AM to micro 5pin或AF to micro 5pin 这里的AM或AF是Type a male和Type a female的简写 Type a male:A型男士 Type a fema ...

  2. Python GUI开发环境的搭建

    原文:Python GUI开发环境的搭建 最近对Python的开发又来了兴趣,对于Python的开发一直停留在一个表面层的认识,玩的部分比较大. Python的入手简单,语法让人爱不释手,在网络通信方 ...

  3. Html 小插件9 腾讯新闻

    地址:http://minisite.qq.com/others08/ 效果:

  4. 怎样从一个DLL中导出一个C++类

    原文作者:Alex Blekhman    翻译:朱金灿 原文来源: http://www.codeproject.com/KB/cpp/howto_export_cpp_classes.aspx 译 ...

  5. Swift中的UIKit重力学

    前言: 重力学这个名词不论在哪个行业领域听起来似乎都非常高大上. 那么在Swift中的重力学是什么呢?那就是将我们移动端屏幕上毫无生命力的东西也置于万有引力中.使它们能够展现出好像真的因为引力而向下坠 ...

  6. [HDU 4741]Save Labman No.004[计算几何][精度]

    题意: 求两条空间直线的距离,以及对应那条距离线段的两端点坐标. 思路: 有一个参数方程算最短距离的公式, 代入求即可. 但是这题卡精度... 用另外的公式(先算出a直线上到b最近的点p的坐标, 再算 ...

  7. flexbox 伸缩布局盒

    Flexbox(伸缩布局盒) 是 CSS3 中一个新的布局模式,为了现代网络中更为复杂的网页需求而设计. Flexbox 由 伸缩容器 和 伸缩项目 组成.通过设置元素的 display 属性为   ...

  8. JavaScript 深入学习及常用工具方法整理 ---- 01.浮点数

    在JavaScript中是不区分整数值和浮点数值的,其中所有的数字均用浮点数值表示.JavaScript采用IEEE 754标准(有兴趣可以浏览网络规范分类下的IEEE 754标准,需要原文件请在留言 ...

  9. Python学习笔记 (2) :字符串输出、操作、格式化和日期、时间格式化

    一.字符串输出及运算 1.常用输出格式及方法 ')#单引号 ")#双引号 """)#三个引号 1234567890 1234567890 1234567890 ...

  10. setTimeout 虚假的“异步”

    看这篇http://www.laruence.com/2009/09/23/1089.html 所以实际上 setTimeout更像是任务按照队列执行  经过setTimeout设置后任务放在了队尾 ...