Android心跳包(一)——心跳实现

分享一种Android端IM即时通讯智能心跳算法 对于IM或实时消息推送技术来说,客户端的心跳算法几乎是必备品,尤其当前复杂的移动网络环境下,网络心跳保活算法的优劣更是决定了您的APP即时数据收发的实时性和用户体验,非常地关键。 为什么TCP连接需要心跳?因为运营商有一个NAT超时:因为IP v4的IP量有限,运营商分配给手机终端的IP是运营商内网的IP,手机要连接Internet,就需要通过运营商的网关做一个网络地址转换(Network Address Translation,NAT)。简单的说运营商的网关需要维护一个外网IP、端口到内网IP、端口的对应 阅读详情

长连接

测试服务器: 
Socket基本上都这么一个流程。

public class Test {

    private static final int PORT = 1234;  

    private static final int BUFFER_SIZE = 1024; 

    public static void main(String[] args) {
        ServerSocket ss;
        try {
            ss = new ServerSocket(PORT);
            Socket s = ss.accept();
            byte[] recData = null;  
            InputStream in = s.getInputStream();  
            OutputStream out = s.getOutputStream();  
            while(true) {  
                recData = new byte[BUFFER_SIZE];  
                int r = in.read(recData);  
                //int r = in.read(recData);  
                if(r>-1) {  
                    String data = new String(recData);  
                    if(data.trim().equals("over")) {  
                        s.close();  
                    }  
                    System.out.println("读取到客户端发送的来数据:"+data);  
                    out.write("这是服务端发给客户端的数据:".getBytes());  
                    out.write(recData);  
                }else {  
                    System.out.println("数据读取完毕!");  
                    s.close();  
                    System.exit(0);  
                    //ss.close();  
                }  
            }  

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

这个就是读客户端传过来的数据。 
客户端我写在了android上,一个click事件:

    public void test(View v) {
        new Thread(new Runnable() {

            @Override
            public void run() {
                try {
                    Socket s = new Socket(serv,port);
                    PrintWriter out = new PrintWriter(s.getOutputStream());
                    while (true) {
                        Thread.sleep(5000);
                        String msg = "me";
                        out.println(msg);
                        out.flush();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }               
            }
        }).start();
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

启动Server后,效果如下,每5秒钟会收到客户端发的消息: 
这里写图片描述

这个就是长连接,如果不关掉服务器,会一直接收某个客户端的消息。

短连接

服务器代码:

public class Test {

    private static final int PORT = 1234;  

    private static final int BUFFER_SIZE = 1024; 

    public static void main(String[] args) {
        ServerSocket ss;
        try {
            ss = new ServerSocket(PORT);
            Socket s = ss.accept();
            //主要是这一句
            s.setSoTimeout(2000);
            byte[] recData = null;  
            InputStream in = s.getInputStream();  
            OutputStream out = s.getOutputStream();  
            while(true) {  
                recData = new byte[BUFFER_SIZE];  
                int r = in.read(recData);  
                //int r = in.read(recData);  
                if(r>-1) {  
                    String data = new String(recData);  
                    if(data.trim().equals("over")) {  
                        s.close();  
                    }  
                    System.out.println("读取到客户端发送的来数据:"+data);  
                    out.write("这是服务端发给客户端的数据:".getBytes());  
                    out.write(recData);  
                }else {  
                    System.out.println("数据读取完毕!");  
                    s.close();  
                    System.exit(0);  
                    //ss.close();  
                }  
            }  

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

客户端代码:

    public void test(View v) {
        new Thread(new Runnable() {

            @Override
            public void run() {
                try {
                    Socket s = new Socket(serv,port);
                    PrintWriter out = new PrintWriter(s.getOutputStream());
                    while(true){
                        String msg = "me";
                        out.println(msg);
                        out.flush();
                        Thread.sleep(3000);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }               
            }
        }).start();
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

可以看到,客户端是3秒发一次消息,而服务器设置的是2秒超时。所以只能接收到一次消息,然后就关闭了socket。 
这里写图片描述
如果不想报错,就把服务器的while(true)循环放到Socket s = ss.accept();外面。意思是,为每个客户端分配的连接时长是2秒,超过以后就中断这个socket,除非重新建立连接。

心跳包

长连接占用系统资源,但是短连接会造成连接中断。所以综合这两种情况,提出一个心跳包的概念。就是给服务器设置超时,比如上面的2秒,然后客户端发空的消息,或约定好的字符串格式,当然间隔时长需要在超时以内(比如这里就需要在2秒以内)来给服务器保证这个连接(即这个socket)不被销毁。

服务器代码:

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;


public class Test {

    private static final int PORT = 1234;  

    private static final int BUFFER_SIZE = 1024; 

    public static void main(String[] args) {
        ServerSocket ss = null;
        try {
            ss = new ServerSocket(PORT);
            Socket s = ss.accept();
            s.setSoTimeout(2000);
            byte[] recData = null;  
            InputStream in = s.getInputStream();  
            OutputStream out = s.getOutputStream();  
            while(true) {  
                recData = new byte[BUFFER_SIZE];  
                int r = in.read(recData);  
                //int r = in.read(recData);  
                if(r>-1) {  
                    String data = new String(recData);  
                    if(data.trim().equals("over")) {  
                        s.close();  
                    }  
                    System.out.println("读取到客户端发送的来数据:"+data);  
                    out.write("这是服务端发给客户端的数据:".getBytes());  
                    out.write(recData);  
                }else {  
                    System.out.println("数据读取完毕!");  
                    s.close();  
                    System.exit(0);  
                    //ss.close();  
                }  
            }  

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48

客户端代码:

public void test(View v) {
        new Thread(new Runnable() {

            @Override
            public void run() {
                try {
                    Socket s = new Socket(serv,port);
                    PrintWriter out = new PrintWriter(s.getOutputStream());
                    while(true){
                        String msg = "me";
                        out.println(msg);
                        out.flush();
                        //这里改成1秒了
                        Thread.sleep(1000);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }               
            }
        }).start();
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

这样就保持了一个长连接。这个就可以看做心跳包。 
实际使用时比这个要复杂,但大概就是这个原理。

android系列之——心跳包学习总结 **心跳包**:所谓心跳包,指的是客户端每隔一段时间发一个空消息给服务端,以防止服务端关闭已连接的端口;因酷似心脏一样有规律的跳动,也相当于是告诉服务端我这个端口的客户端还在线;所以称之为心跳包。 实现步骤: 一、在工具类包里写一个心跳包类hartbeatPackage,继承Thread类, 将此类写成单例模式,在构造方法里启动线程;创建一个实例instend; 创建一个静态方法供外界调用此类 阅读详情

相关推荐

Android实现心跳的效果

最近再做一个教育类的项目。在做一些学习工具的时候,美工提出了一些要求,大致如下: 其实实现过程也不难,大致就是对一个视图控件添加一个圆形的背景,然后该视图进行动画处理,膨胀的同时,透明度增大,收缩的同时,透明度降低。 我在例子中是使用了TextView,所以首先对TextView添加一个圆形的背景: <shape xmlns:android="http://schemas.android.

Shawn1992的学习笔记 4677

android 定时器发送心跳包,AndroidStudio_在android中使用定时器_异步定时实现心跳保活功能---Android原生开发工作笔记231...

其实就是定时去给服务器,发送心跳,给服务器提供简单的监控功能.这里不能简单的用Timer实现,会出现阻塞的情况,要使用timer和Handler结合的方式实现在不影响界面的情况下,异步发送心跳.下面的代码可以直接copy过去就用吧1.第一个30000是延时30秒执行,然后第二个30000是每隔30秒执行一次//30秒保活一次private void startKeepAliveService() ...

weixin_42413455的博客 503

Android实现动态心跳图 (附完整源码)

Android实现动态心跳图 (附完整源码)

希望我的博客,能帮上你解决学习中工作中所遇到的问题 475

Android Socket通讯 之 心跳消息

不知道大家国庆节过的咋样,有没有学习呢?我是闲着没事就写点东西,本文篇幅较短,只是实现了心跳消息的处理,下面进入正文。

晨曦 4672

android心跳包

里面封装了 tcp心跳包机制 欢迎大家学习

Android的socket长连接(心跳检测)

这是Android的socket长连接(心跳包),由于本人项目中需要用到长连接,所以先做了个demo,亲测是没有问题的。

Android xmpp+openfire+smack 断线问题解决方案

       用smack库写Android端聊天的功能的同学可能都有一个困扰,就是应用切换到后台,或者锁屏一会儿,回来以后发现消息发不出去了,此时去openfire后台查看自己这个账号,显示是下线的,但是打断点,调用connection的isConnect方法,发现返回的竟然是true,也就是说没有办法主动判断自己是否在线,长链接是否依然存在。       smack提供了reconnect的...

xu404741377的博客 1806

DASH 流媒体协议(Dynamic Adaptive Streaming over HTTP)概述——起源、MPD文件解析、相关项目

简单介绍DASH的起源与发展、MPD文件简要解析、相关项目,以及常见流媒体协议的比较

farewellyi的博客 6891

androidpn-client重要BUG-锁屏掉线解决方法

在网上androidpn上的BUG基本都解决了,也多亏牛人们顶力相助,灰常感谢啊。在这里要说的问题是手机锁屏后,客户端心跳包不再发送了。由于android也接触不是很久,对一些系统的机制不太了解,经过多次测试与分析,才发现了是由于锁屏后CPU处于睡眠状态,线程都被挂起,所以在服务器端设定的闲置时间内收不到心跳包,强制移除用户下线。       OK问题已经找到了就好办多了,既然是被挂起了我们就只

kingsonl的专栏 6091

解密DS90UB983-Q1的汽车电子魔法:如何通过FPD-Link IV实现4K视频的无缝传输

本文深入解析了德州仪器DS90UB983-Q1串行器芯片如何通过FPD-Link IV技术在汽车电子中实现4K视频无缝传输。文章详细介绍了该技术的核心功能,包括多流传输(MST)模式、热插拔检测(Hot Plug Detect)机制以及电磁兼容性设计,为车载信息娱乐系统提供了高带宽、低延迟的可靠解决方案。

i3j4k5的博客 244

Unity卡通渲染实战:原神PMX模型Blender转FBX全流程

卡通渲染是二次元游戏开发的核心技术之一,其本质在于对光照模型、顶点色控制与边缘光生成的精准建模。本文从基础概念切入,解析MMD PMX格式的数据结构原理,阐明顶点色(Vertex Color)与Toon Ramp贴图在风格化渲染中的技术价值;进而覆盖Blender到Unity的跨引擎资产流转关键路径,重点解决法线校准、骨骼命名适配、FBX导出参数配置等工业级断点问题;最终落地于Unity内置管线与URP双环境下的卡通Shader定制与Render Feature实现。内容聚焦原神风格角色资产重铸实践,涵盖P

weixin_38166557的博客 438

android 心跳包,android socket 发送心跳包

在项目中,有如下需求:Android客户端向服务器发送数据,收到服务器返回的数据发送成功标识后,客户端即与服务器建立数据一来一往的心跳连接,若服务器端断开时,客户端接收到通知,关闭Service停止发送数据;代码如下:publicclassBackServiceextendsService{privatestaticfinalStringTAG="BackService";/...

weixin_31429257的博客 766

《BiLSTM with Multi-Polarity Orthogonal Attention for Implicit Sentiment Analysis》论文阅读笔记

文章名:《BiLSTM with Multi-Polarity Orthogonal Attention for Implicit Sentiment Analysis》 作者Jiyao Wei a,1, Jian Liaoa,1, Zhenfei Yanga, Suge Wanga,b,∗, Qiang Zhaoa 年份 2019 1 Introduction 目前文本情感分析多分析带...

weixin_39036944的博客 1631

Android心跳包(一)——心跳机制

转自:http://blog.youkuaiyun.com/rabbit_in_android/article/details/50119809 在写之前,我们首先了解一下为什么android维护长连接需要心跳机制,首先我们知道,维护任何一个长连接都需要心跳机制,客户端发送一个心跳给 服务器,服务器给客户端一个心跳应答,这样就形成客户端服务器的一次完整的握手,这个握手是让双方都知道他们之间的连

闲暇部落 1万+

基于FPGA的DDR学习——1.基础知识

⚪DDR2(Double Data Rate2)SDRAM是由JEDEC(电子设备工程联合委员会)开发的第三代SDRAM内存技术标准,1.8V工作电压,240线接口,提供了相较于DDR SDRAM更高的运行效能与更低的电压,同样采用在时钟的上升/下降沿同时进行数据传输的基本方式,但拥有两倍于上一代DDR内存预读取能力(即4bit数据预取能力),其常见的频率规范有DDR2 400\533\667\800\1066\1333等,总线频率553MHZ的DDR2内存只需133MHZ的工作频率。

qq_44932488的博客 2071

【通信协议】I2C总线(一主多从)

I2C总线(一主多从)之软件模拟代码详解

m0_75090944的博客 9844

Android service心跳实现的两种方式

这里简单介绍两种实现心跳的方式。 第一种,简单粗暴线程实现 new Thread(new Runnable() { @Override public void run() { while (true) { try { ...

ovejur的专栏 3495

Android 14.0 开机广播接收慢广播延迟问题分析

在14.0的系统rom定制化开发中,在某些时候在接收开机广播的时候发现,过了一分钟才收到开机广播,接下来就需要分析下 开机广播的相关分发机制,来处理下相关问题

安卓兼职framework和app工程师的博客 631

android socket 实现心跳包

//开一个新线程 new Thread(){ //用handle处理要发送的数据 Handler handler = new Handler(){ public void handleMessage(Message msg) { switch (msg.what) { case 1:

mobei1983的博客 2226

RHEL 8 与 RHEL 7 与 RHEL 6 的比较,RHEL 8强到离谱!

Red Hat Enterprise Linux(RHEL)是企业级 Linux 发行版中最受欢迎的操作系统之一。RHEL 为服务器和企业环境提供了高性能、稳定性和安全性,适用于各种数据中心和云计算平台。自 RHEL 6 以来,Red Hat 对其操作系统进行了多次重大更新,RHEL 7 和 RHEL 8 带来了许多新的特性、工具和架构变化。

网络技术联盟站 710

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

安卓常见建立心跳连接

安卓使用tcp 建立心跳连接: 方法如下: private void initTcpConnect(){ //先初始化timerTask if (tcpTask != null){ tcpTask.cancel(); tcpTask= null; } if (tcpTimer== nul...

weixin_42682455的博客 654

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Android TCP长连接 心跳机制及实现

背景知识 智能手机上的长连接心跳和在Internet上的长连接心跳有什么不同 Android系统的推送和iOS的推送有什么区别 几种推送的实现方式 协议 1XMPP简介 2 MQTT简介 3移动端消息推送 xmpp 和 mqtt 哪个更费电 心跳代码实现 Demo建立一个带有心跳检测的SocketDemo 维护任何一个长连接都需要心跳机制,客户端发送一个心跳给服务器,服务器给客户端一个心跳应答,

TTKatrina的博客 1万+

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

Android端消息推送总结:实现原理、心跳保活、遇到的问题等

Android端消息推送总结:实现原理、心跳保活、遇到的问题等

idaretobe的专栏 4134

android心跳包作用,Android开发Im总结-5:心跳包

心跳包的作用:TCP长连接本质上不需要心跳包来维持, 大家可以试一试, 让两台电脑连上同一个wifi, 然后让其中一台做服务器, 另一台用一个普通的没有设置KeepAlive的Socket连上服务器, 只要两台电脑别断网, 路由器也别断电, DHCP正常续租, 就这么放着, 过几个小时再用其中一台电脑通过之前建立的TCP连接给另一台发消息, 另一台肯定能收到。那为什么要有心跳包呢? 其实主要是为了...

weixin_39880479的博客 677

Android心跳包(一)——心跳包定义

1、定义      心跳包就是在客户端和服务器间定时通知对方自己状态的一个自己定义的命令字,按照一定的时间间隔发送,类似于心跳,所以叫做心跳包。 2、作用 网络中的接收和发送数据都是使用SOCKET进行实现。但是如果此套接字已经断开,那发送数据和接收数据的时候就一定会有问题。可是如何判断这个套接字是否还可以使用呢?这个就需要在系统中创建心跳机制。其实TCP中已经为我们实现了一个叫做心

闲暇部落 2340
上一篇: Android心跳包(一)——心跳包定义
下一篇: Android心跳包(一)——心跳机制
闲暇部落
博客等级 码龄12年 2777粉丝 215原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

闲暇部落

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值