在Android设备中接收UDP广播时丢包 [英] Packet loss while receiving UDP broadcast in android device

查看:837
本文介绍了在Android设备中接收UDP广播时丢包的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为了接收从服务器到android设备的UDP广播数据包,我使用了服务类并在线程中侦听数据包.它成功接收到数据包.问题是,如果同时从服务器发送多个数据包,则会导致数据包丢失.

我什至尝试使用队列并在单独的线程中处理接收到的数据包,然后我也没有得到数据包.我是网络编程的新手,将不胜感激

void startListenForUdpBroadcast() {
        UDPBroadcastThread = new Thread(new Runnable() {
            public void run() {
                try {
                    InetAddress broadcastIP = InetAddress.getByName(UdpConstants.IP_ADDRESS);
                    Integer port = UdpConstants.RECEIVER_PORT;
                    while (shouldRestartSocketListen) {
                        listenAndWaitAndThrowIntent(broadcastIP, port);
                    }

                } catch (Exception e) {
                    Log.i("UDP", "no longer listening for UDP broadcasts cause of error " + e.getMessage());
                }
            }
        });
        UDPBroadcastThread.setPriority(Thread.MAX_PRIORITY); //Setting The Listener thread to MAX PRIORITY to minimize packet loss.
        UDPBroadcastThread.start();
    }

此代码侦听新数据包并推送到队列

private void listenAndWaitAndThrowIntent(InetAddress broadcastIP, Integer port) throws Exception {
        byte[] recvBuf = new byte[64000];
        if (socket == null || socket.isClosed()) {
            socket = new DatagramSocket(port, broadcastIP);
            socket.setBroadcast(true);
        }
//socket.setSoTimeout(1000);
        DatagramPacket packet = new DatagramPacket(recvBuf, recvBuf.length);

        socket.receive(packet);
        messQueue.add(packet);

    }

这将检查队列中是否有新消息并对其进行处理

 /**
     * @purpose Checking queue and If anything is added to the queue then broadcast it to UI
     */
    private void checkQueue() {
        queueThread = new Thread(new Runnable() {
            public void run() {
                try {

                    while (shouldRestartSocketListen) {
                        if (!messQueue.isEmpty()) {
                            broadcastIntent(messQueue.poll());
                        }
                    }

                } catch (Exception e) {

                }
            }
        });
        queueThread.start();
    }

解决方案

我认为您的问题主要是您在wifi上使用了Udp广播.

他们有两个非常有据可查的答案,为什么这是一种非常慢的操作方式,以及为什么会有更多的数据包丢失:

我为解决极慢的带宽所做的事情是某种多单播协议:

  1. 管理已连接的客户端列表.
  2. 通过发送呼叫,将服务器中的每个数据包分别发送给所有客户端.

这是java中的代码:

  DatagramPacket packet = new DatagramPacket(buffer, size);
  packet.setPort(PORT);

  for (byte[] clientAddress : ClientsAddressList) {
        packet.setAddress(InetAddress.getByAddress(clientAddress));
        transceiverSocket.send(packet);
  }

For receiving UDP broadcast packets from the server to an android device, i used a service class and listen for packets in a thread. It receives the packet successfully. The problem is that if multiple packets are being sent from the server in the same time then packet loss will be the result.

I even tried with a queue and processing the received packets in separate thread then also i am not getting the packet. I am completely new to network programming any help would be widely appreciated

void startListenForUdpBroadcast() {
        UDPBroadcastThread = new Thread(new Runnable() {
            public void run() {
                try {
                    InetAddress broadcastIP = InetAddress.getByName(UdpConstants.IP_ADDRESS);
                    Integer port = UdpConstants.RECEIVER_PORT;
                    while (shouldRestartSocketListen) {
                        listenAndWaitAndThrowIntent(broadcastIP, port);
                    }

                } catch (Exception e) {
                    Log.i("UDP", "no longer listening for UDP broadcasts cause of error " + e.getMessage());
                }
            }
        });
        UDPBroadcastThread.setPriority(Thread.MAX_PRIORITY); //Setting The Listener thread to MAX PRIORITY to minimize packet loss.
        UDPBroadcastThread.start();
    }

This code listens for new packets and pushes to queue

private void listenAndWaitAndThrowIntent(InetAddress broadcastIP, Integer port) throws Exception {
        byte[] recvBuf = new byte[64000];
        if (socket == null || socket.isClosed()) {
            socket = new DatagramSocket(port, broadcastIP);
            socket.setBroadcast(true);
        }
//socket.setSoTimeout(1000);
        DatagramPacket packet = new DatagramPacket(recvBuf, recvBuf.length);

        socket.receive(packet);
        messQueue.add(packet);

    }

This checks the queue for new messages and process it

 /**
     * @purpose Checking queue and If anything is added to the queue then broadcast it to UI
     */
    private void checkQueue() {
        queueThread = new Thread(new Runnable() {
            public void run() {
                try {

                    while (shouldRestartSocketListen) {
                        if (!messQueue.isEmpty()) {
                            broadcastIntent(messQueue.poll());
                        }
                    }

                } catch (Exception e) {

                }
            }
        });
        queueThread.start();
    }

解决方案

I think your problem is mainly that you use Udp Broadcast over wifi.

Their are two very well documented answers why this is a very slow way to operate and why there are much more packet losts:

The thing I did to solve the extremely slow bandwidth was some kind of multi-unicast protocol:

  1. Manage the list of clients you have connected.
  2. Send each packet you have in your server to all of your clients separately with send call.

This is the code in java:

  DatagramPacket packet = new DatagramPacket(buffer, size);
  packet.setPort(PORT);

  for (byte[] clientAddress : ClientsAddressList) {
        packet.setAddress(InetAddress.getByAddress(clientAddress));
        transceiverSocket.send(packet);
  }

这篇关于在Android设备中接收UDP广播时丢包的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆