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

长连接

测试服务器: 
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

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

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个使用新线程循环发送心跳包的示例代码: ```java public class HeartbeatThread extends Thread { private final String TAG = "HeartbeatThread"; private final int HEARTBEAT_INTERVAL = 5000; // 心跳包发送间隔,单位为毫秒 private boolean isRunning = false; // 标志位,用于控制线程运行状态 @Override public void run() { isRunning = true; while (isRunning) { try { // 发送心跳包 // ... Thread.sleep(HEARTBEAT_INTERVAL); // 线程休眠,等待下一次发送心跳包 } catch (InterruptedException e) { Log.e(TAG, "HeartbeatThread interrupted!"); e.printStackTrace(); } } } public void stopThread() { isRunning = false; } } ``` 在使用该线程时需要注意,在发送心跳包的同时,需要在主线程中处理接收到的心跳回包,以保证心跳功能的正常运行。可以使用Handler或者BroadcastReceiver来实现。 另外,需要注意线程的停止问题。在Activity或者Service销毁时,应该调用stopThread()方法来停止心跳线程,避免出现内存泄漏的情况。 ```java public class MainActivity extends AppCompatActivity { private HeartbeatThread mHeartbeatThread; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mHeartbeatThread = new HeartbeatThread(); mHeartbeatThread.start(); } @Override protected void onDestroy() { super.onDestroy(); if (mHeartbeatThread != null) { mHeartbeatThread.stopThread(); mHeartbeatThread = null; } } } ``` 需要注意的是,该示例代码仅供参考,具体实现还需要根据具体的业务需求来进行调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值