android java代码UDP通信---接收数据的流程

1 篇文章 0 订阅

什么是UDP协议以及它的使用优点:百度的解释是这样的:Internet 协议集支持一个无连接的传输协议,该协议称为用户数据报协议(UDP,User Datagram Protocol)。UDP 为应用程序提供了一种无需建立连接就可以发送封装的 IP 数据包的方法。

  1. 不需要要建立连接
  2. 开销小
  3. 速度快

一:udp通信主要使用的场景:

比如设备监控,监控设备是否脱机,目前我主要是用于在同一个局域网内模拟设备给手机app发送数据,app界面需要显示该设备的一个工作情况,比如车辆的转速 工作时间 当前电量 待机 预热情况等,那么中间就有一个接收模拟设备发送过来的报文数据,以及当我接收完数据的一个显示情况,作为app端只需要接收数据,所以下面的内容主要是介绍app端接收udp的报文数据。

二:udp通信  接收数据方的流程:

  • 创建Socket对象 ( DatagramSocket)
  • 创建一个接收数据的包  (DatagramPacket)下面代码创建了一个接收线程 每沉睡20毫秒后receive数据
  • 解析数据包 大致代码如下
private DatagramSocket receiveSocket = null;// 接收数据Socket
private DatagramPacket rPacket = null;
private DatagramPacket packet = null;
private Thread rthread = null;// 接收数据线程
/*** 接收数据socket连接 ***/
private void connectSocket() {

    DisConnectSocket();
    try {

        if (receiveSocket == null) {
            receiveSocket = new DatagramSocket(null);
            receiveSocket.setReuseAddress(true);
            receiveSocket.bind(new InetSocketAddress(port));
        }
        if (rPacket == null) {
            rPacket = new DatagramPacket(rBuffer, rBuffer.length);
        }
        if (rthread == null) {
            //创建接收线程
            ReceiveDataThread receiveDataThread = new ReceiveDataThread();
            rthread = new Thread(receiveDataThread);
            rthread.start();
        }

    } catch (Exception e) {
        e.printStackTrace();
        ToastUtils.showShort("连接本地端口:" + localPort + "失败,异常代码:" + e.getMessage(),Toast.LENGTH_LONG);
        DisConnectSocket();
    }
}
class ReceiveDataThread implements Runnable {
        @Override
        public void run() {
            Boolean aBoolean = false;
            if(Thread.currentThread() == rthread){
                while (Thread.currentThread() == rthread) {
                       
                        //接收报文数据
                        recvData();

                        Thread.sleep(20);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
/****
 * 接收数据
 *
 * @return
 */
private boolean recvData() {
    try {
        if (receiveSocket != null) {
            try {
                //设置超时时间
                receiveSocket.setSoTimeout(2000);
                receiveSocket.receive(rPacket);
                // sRecvData 是接收到的报文数据
                if (isRHex) {
                    sRecvData = recvHexData(rPacket.getLength());
                } else {
                    sRecvData = new String(rPacket.getData(), currentRCodes)
                            .trim();
                }
            aBoolean = false;
            } catch (Exception e) {
                sRecvData = null;
                aBoolean = true;
            }

        } else {
            ToastUtils.showShort("没有连接本地端口!",Toast.LENGTH_LONG);
            return false;
        }
        return aBoolean;
    } catch (Exception e) {
      //  ToastUtils.showShort("接收数据错误,异常代码:"+ e.getMessage(),Toast.LENGTH_LONG);
        return aBoolean;
    }
}

三:我遇到的问题

当模拟设备不给app端发数据时需要清空界面数据,can转WiFi模块(模拟设备)设置的是20毫秒会发送一次数据,但udp通信是没有接收到数据会处于阻塞状态,receive();方法会一直等待数据接收,直到有数据接收到的时候就会结束阻塞,解决方法: receiveSocket.setSoTimeout(2000); 设置2s超时等待,如果2s还是没有接收到数据就抛出异常,那么就可以在catch里面去调用界面参数的清空方法。

 

     

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值