Android中UDP多播中的数据包丢失

MMJ

我创建了一个应用程序,该应用程序提供了android中UDP数据包丢失的统计信息。这是我的应用程序体系结构。1)多播UDP数据包的应用程序。下面是它的代码:

package rockwell.multicastserverproj;

import android.content.Context;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;

public class MainActivity extends AppCompatActivity {

    EditText txtMsg;
    EditText txtPackets;
    EditText txtMs;
    EditText txtBytes;
    EditText txtCount;
    byte[] rtpData;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();

            }
        });

        /*Thread thrClient = new Thread(new ReceiveMulticast());
        thrClient.start();*/

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    public void onBtnClicked(View view)
    {
        Thread threadTotalPackets = new Thread(new SendMulticast());
        threadTotalPackets.start();

        Thread thread = new Thread(new MulticastPackets());
        thread.start();
        //Toast.makeText(this,"Message multicasted",Toast.LENGTH_LONG).show();


    }

    public class MulticastPackets implements Runnable{

        @Override
        public void run() {
            InetAddress group = null;
            MulticastSocket multiSocket = null;
            int PORT = 6500;
            txtPackets =(EditText)findViewById(R.id.txtPackets);
            txtMs = (EditText)findViewById(R.id.txtMs);
            txtBytes = (EditText)findViewById(R.id.txtBytes);
            txtCount = (EditText)findViewById(R.id.txtCount);

            int noOfPackets = Integer.parseInt(txtPackets.getText().toString());
            int delayMS = Integer.parseInt(txtMs.getText().toString());
            int packetSize = Integer.parseInt(txtBytes.getText().toString());
            int cntPacket = Integer.parseInt(txtCount.getText().toString());

            WifiManager wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
            WifiManager.MulticastLock mLock = wifi.createMulticastLock("mylock");
            mLock.acquire();

            try{
                group = InetAddress.getByName("230.0.0.1");
                multiSocket = new MulticastSocket(PORT);
            } catch (IOException e) {
                e.printStackTrace();
            }

            for(int pcktCnt=1; pcktCnt<=noOfPackets; pcktCnt++) {

                rtpData = new byte[packetSize];
                int cnt = unsigned_int(pcktCnt);
                byte[] seqArr = null;
                seqArr = toBytes(cnt);
                byte varFirst = 0xa;
                byte varSecond = 0x5;

                for(int i=4;i<packetSize;i+=2)
                {
                    if(i%4 ==0) {
                        rtpData[i] = varFirst;
                        rtpData[i + 1] = varFirst;
                    }
                    else {
                        rtpData[i] = varSecond;
                        rtpData[i + 1] = varSecond;
                    }
                }

                for(int i=0;i<4;i++)
                {
                    rtpData[i] = seqArr[i];
                }

                DatagramPacket requestPacket = new DatagramPacket(rtpData, rtpData.length, group, PORT);
                try {
                    for(int i=0;i<cntPacket;i++) {
                        multiSocket.send(requestPacket);
                        Thread.sleep(delayMS, 0);
                    }
                    int test = fromByteArray(seqArr);
                    Log.i("Multicast", "Packet send. Sequence number is: " + test);

                } catch (Exception e) {
                    e.printStackTrace();
                }
                int test = fromByteArray(seqArr);
            }

            try{

                multiSocket.leaveGroup(group);
                multiSocket.close();

            } catch (IOException e) {
                e.printStackTrace();
            }
            mLock.release();

            MainActivity.this.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    Toast.makeText(MainActivity.this,"Packet sent",Toast.LENGTH_LONG).show();
                }
            });
        }
    }

    public class SendMulticast implements Runnable{
        @Override
        public void run() {
            InetAddress group = null;
            MulticastSocket multiSocket = null;
            int PORT = 5500;
            txtPackets =(EditText)findViewById(R.id.txtPackets);
            txtBytes = (EditText)findViewById(R.id.txtBytes);

            String requestString = txtPackets.getText().toString();
            String strPackSize = txtBytes.getText().toString();

            requestString = requestString +";" + strPackSize;
            Log.i("reqstring",requestString);
            byte[] requestData = new byte[requestString.length()];
            requestData = requestString.getBytes();

            WifiManager wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
            WifiManager.MulticastLock mLock = wifi.createMulticastLock("mylock");
            mLock.acquire();

            try{
                group = InetAddress.getByName("230.0.0.1");
                multiSocket = new MulticastSocket(PORT);
                multiSocket.joinGroup(group);
            } catch (IOException e) {
                e.printStackTrace();
            }

            try{
                DatagramPacket requestPacket = new DatagramPacket(requestData, requestData.length, group, PORT);
                multiSocket.send(requestPacket);
                Log.i("multicastproj","message multicasted");

            } catch (IOException e) {
                e.printStackTrace();
            }
            try{
                multiSocket.leaveGroup(group);
                multiSocket.close();

            } catch (IOException e) {
                e.printStackTrace();
            }
            mLock.release();
        }
    }

    static int unsigned_int(int nb) {
        if (nb >= 0)
            return (nb);
        else
            return (256 + nb);
    }

    public byte[] toBytes(int i)
    {
        byte[] result = new byte[4];

        result[0] = (byte) (i >> 24);
        result[1] = (byte) (i >> 16);
        result[2] = (byte) (i >> 8);
        result[3] = (byte) (i /*>> 0*/);

        return result;
    }

    public int fromByteArray(byte[] bytes) {
        return bytes[0] << 24 | (bytes[1] & 0xFF) << 16 | (bytes[2] & 0xFF) << 8 | (bytes[3] & 0xFF);
    }



    public class ReceiveMulticast implements Runnable{
        @Override
        public void run() {
            byte[] requestData = new byte[1024];
            InetAddress group = null;
            MulticastSocket multiSocket = null;
            int PORT = 4500;

            WifiManager wifi = (WifiManager) getSystemService(getApplicationContext().WIFI_SERVICE);
            WifiManager.MulticastLock mLock = wifi.createMulticastLock("mylock");
            mLock.acquire();

            try{
                group = InetAddress.getByName("230.0.0.1");
                multiSocket = new MulticastSocket(PORT);
                multiSocket.joinGroup(group);
            } catch (IOException e) {
                e.printStackTrace();
            }

            try{
                while(true)
                {
                    DatagramPacket requestPacket = new DatagramPacket(requestData, requestData.length);
                    multiSocket.receive(requestPacket);

                    String requestString = new String(requestPacket.getData(), 0, requestPacket.getLength());
                    Log.d("CreateMulticastServer", "Got request = " + requestString);

                    /*txtMsg = (EditText)findViewById(R.id.txtMsg);
                    txtMsg.setText(requestString);*/
                }

            } catch (IOException e) {
                e.printStackTrace();
            }

            try{
                multiSocket.leaveGroup(group);
                multiSocket.close();

            } catch (IOException e) {
                e.printStackTrace();
            }

            mLock.release();

        }
    }
}

另一个接收那些组播UDP数据包的应用程序

连续运行并接收多播数据包的服务:

package rockwell.packetstatistics;

import android.app.IntentService;
import android.content.Context;
import android.content.Intent;
import android.net.wifi.WifiManager;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;

/**
 * Created by mmjoshi on 2/10/2016.
 */
public class PacketReceive_Service extends IntentService {
    boolean flag = true;
    int packetSize = 0;
    public PacketReceive_Service() {
        super("PacketReceive_Service");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        String strVar = intent.getStringExtra("vari");
        Log.i("onstartservice","string is " + strVar);

        Thread thread = new Thread(new PacketThread());
        thread.setPriority(Thread.MAX_PRIORITY);
        thread.start();

        Thread thread1 = new Thread(new TotalPackets());
        thread1.start();
    }

    public class PacketThread implements Runnable
    {
        @Override
        public void run() {
            InetAddress group = null;
            MulticastSocket multiSocket = null;
            WifiManager.MulticastLock mLock = null;
            int prevSeqNo=0;
            String strMissingPackets="";
            int TotalpacketsReceived = 0;
            try {

                if(packetSize == 0)
                    packetSize = 1036;

                byte[] requestData = new byte[packetSize];
                int PORT = 6500;
                byte varFirst = 0xa;
                byte varSecond = 0x5;

                WifiManager wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
                mLock = wifi.createMulticastLock("mylock");
                mLock.setReferenceCounted(true);
                mLock.acquire();

                try{
                    group = InetAddress.getByName("230.0.0.1");
                    multiSocket = new MulticastSocket(PORT);
                    multiSocket.joinGroup(group);
                } catch (IOException e) {
                    e.printStackTrace();
                }

                while (flag) {
                    final DatagramPacket requestPacket = new DatagramPacket(requestData, requestData.length);
                    multiSocket.receive(requestPacket);

                    byte[] resultData = requestPacket.getData();

                    byte[] seqArr = new byte[4];
                    for(int i=0;i<4;i++){
                        seqArr[i] = resultData[i];
                    }

                    int seqNo = fromByteArray(seqArr);
                    Log.i("RecvPackets","multiple packet received # is: " + seqNo);
                    if(prevSeqNo!=seqNo)
                    {
                        TotalpacketsReceived++;
                        if(prevSeqNo!=0)
                        {
                            if((seqNo - prevSeqNo)>1)
                            {
                                for(int k=(prevSeqNo+1);k<seqNo;k++)
                                {
                                    strMissingPackets += k + ", ";
                                    sendResultMessage("Missing;" + String.valueOf(k));
                                    Log.i("RecvPackets","Packet missing. Missing# is: " + k);
                                }
                            }
                        }
                        for(int i=4;i<packetSize;i+=2)
                        {
                            if(i%4 ==0) {
                                if(resultData[i] != varFirst ||  resultData[i+1] != varFirst)
                                {
                                    if(seqNo != 1) {
                                        sendResultMessage("DataError;" + String.valueOf(seqNo));
                                        Log.i("DataCheck", "Error in data");
                                    }
                                }
                            }
                            else {
                                if(resultData[i] != varSecond ||  resultData[i+1] != varSecond)
                                {
                                    if(seqNo != 1) {
                                        sendResultMessage("DataError;" + String.valueOf(seqNo));
                                        Log.i("DataCheck", "Error in data");
                                    }
                                }
                            }
                        }
                        prevSeqNo = seqNo;
                        Log.i("MulticastService", "Packet size is: " + packetSize + " Packet receive. Sequence number is: " + seqNo);
                        sendResultMessage("TotalPacketsReceived;" + String.valueOf(TotalpacketsReceived));
                    }
                }


            } catch (IOException e) {
                Log.i("DEU Service", "In cache");
                flag = false;
                e.printStackTrace();
            }
            finally {
                try {
                    if(multiSocket != null) {
                        if(group != null)
                            multiSocket.leaveGroup(group);
                        multiSocket.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }

                if(mLock != null)
                    mLock.release();
            }
        }
    }

    private void sendResultMessage(String strPacks) {
        Intent intent = new Intent("intData");
        intent.putExtra("result",strPacks);
        LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
    }
    private void sendTotalPackets(String strPacks) {
        Intent intent = new Intent("intPacket");
        intent.putExtra("result",strPacks);
        LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
    }
    public int fromByteArray(byte[] bytes) {
        return bytes[0] << 24 | (bytes[1] & 0xFF) << 16 | (bytes[2] & 0xFF) << 8 | (bytes[3] & 0xFF);
    }

    public class TotalPackets implements Runnable{
        @Override
        public void run() {
            byte[] requestData = new byte[1024];
            InetAddress group = null;
            MulticastSocket multiSocket = null;
            int PORT = 5500;

            WifiManager wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
            WifiManager.MulticastLock mLock = wifi.createMulticastLock("mylock");
            mLock.acquire();

            try{
                group = InetAddress.getByName("230.0.0.1");
                multiSocket = new MulticastSocket(PORT);
                multiSocket.joinGroup(group);
            } catch (IOException e) {
                e.printStackTrace();
            }

            try{
                while(true)
                {
                    DatagramPacket requestPacket = new DatagramPacket(requestData, requestData.length);
                    multiSocket.receive(requestPacket);

                    String requestString = new String(requestPacket.getData(), 0, requestPacket.getLength());
                    Log.i("requestString",requestString);
                    String[] spltStr = requestString.split(";");
                    packetSize = Integer.parseInt(spltStr[1].toString());
                    Log.i("service","Packet size is: " + spltStr[1].toString() + " Total Packs: " + spltStr[0]);
                    sendTotalPackets(spltStr[0].toString());
                    /*txtMsg = (EditText)findViewById(R.id.txtMsg);
                    txtMsg.setText(requestString);*/
                }

            } catch (IOException e) {
                e.printStackTrace();
            }

            try{
                multiSocket.leaveGroup(group);
                multiSocket.close();

            } catch (IOException e) {
                e.printStackTrace();
            }

            mLock.release();
        }
    }
}

因此,我的问题是,在服务端,当我收到数据包时,大部分的数据包中有5-7%丢失了。这意味着,如果我在接收端以5ms的间隔发送50包到70包时发送了512字节的1000包。

有什么办法可以减少此数据包丢失?还是我的代码有改进的机会,从而可以减少数据包丢失?

提前致谢。

贾伯斯

您无能为力。

  1. UDP是没有交付保证的传输层。

  2. wifi上的数据包丢失将根据接入点及其运行设备的不同品牌/型号/配置而有所不同。

    例如,5 GHz可能会表现更好,因为空气波通常更干净,但不会像2.4 GHz那样穿透墙壁。

并非所有的Android设备都使用相同的wifi无线电。

如果您使用在MAC层进行多播到单播转换的访问点,实际上实际上可以获得0%的数据包丢失。因此,您可以在应用程序软件中使用UDP。然后,接入点在内部进行802.11层的重传。例如,Cisco和Xirrus具有多播到单播转换选项,并且实际上产生了0%的数据包丢失。但是,由于它不能很好地扩展,因此需要付出一定的代价,因为每个多播流都是单独发送到每个预订的设备的。

好吧...您可以用软件做什么...

在多播中丢包“处理”的方法:

前向纠错。

  • 您可以两次发送每个数据包。 AABBCCDDEE
  • 您可以将每个数据包发送两次,但会延迟: ABACBDCED
  • 您可以两次发送部分数据:AABCCDE任何前向纠错方案都会增加带宽并增加延迟。

损失隐瞒

  • 您可以尝试估计损失之间的数据。

您尚未真正说明您的申请,因此很难就如何处理损失提出建议。限制为5ms,听起来您正在传输240个48khz音频帧数据包。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Android udp数据包丢失

来自分类Dev

在某些Android设备上严重UDP数据包丢失

来自分类Dev

在Golang中,如何接收套接字绑定到特定地址/端口的多播数据包?

来自分类Dev

发送源IP等于Python中虚拟接口IP的多播数据包

来自分类Dev

数据包中的 UDP 字节顺序

来自分类Dev

如何接收多播数据包?

来自分类Dev

在Linux中,如果我尽快调用send(),为什么会丢失UDP数据包?

来自分类Dev

50%的udp数据包丢失

来自分类Dev

UDP多播服务器可以在LAN外部发送数据包吗?

来自分类Dev

Java UDP多播,确定哪个组发送了数据包

来自分类Dev

可以看到带有TCPdump / Wireshark的多播数据包,但无法在应用程序中接收到它

来自分类Dev

在python中从UDP数据包中删除填充(Linux)

来自分类Dev

接收PHP中的UDP数据包数据报

来自分类Dev

在PHP中接收UDP数据包数据报

来自分类Dev

traceroute中的数据包丢失是速度节流的迹象吗?

来自分类Dev

在FreeBSD中不使用ICMP捕获数据包丢失

来自分类Dev

如何在Android上运行的Chrome应用中接收UDP广播数据包

来自分类Dev

通过广播接收Unity Android应用程序中的UDP数据包

来自分类Dev

使用同一套接字发送和接收UDP多播数据包

来自分类Dev

监听bash中返回的UDP数据包

来自分类Dev

无法在Python中接收UDP数据包

来自分类Dev

在Windows 10中发送常规UDP数据包

来自分类Dev

在Java中接收UDP而不丢弃数据包

来自分类Dev

在Python的CrossbarServer中从Arduino接收UDP数据包

来自分类Dev

发送从未收到的多播数据包

来自分类Dev

Android BLE通知数据包丢失

来自分类Dev

多播时通过WiFi通过UDP丢失数据

来自分类Dev

数据包丢失(UDP)的纠错码

来自分类Dev

发送UDP数据包似乎会导致不同NIC上的传入数据包丢失

Related 相关文章

  1. 1

    Android udp数据包丢失

  2. 2

    在某些Android设备上严重UDP数据包丢失

  3. 3

    在Golang中,如何接收套接字绑定到特定地址/端口的多播数据包?

  4. 4

    发送源IP等于Python中虚拟接口IP的多播数据包

  5. 5

    数据包中的 UDP 字节顺序

  6. 6

    如何接收多播数据包?

  7. 7

    在Linux中,如果我尽快调用send(),为什么会丢失UDP数据包?

  8. 8

    50%的udp数据包丢失

  9. 9

    UDP多播服务器可以在LAN外部发送数据包吗?

  10. 10

    Java UDP多播,确定哪个组发送了数据包

  11. 11

    可以看到带有TCPdump / Wireshark的多播数据包,但无法在应用程序中接收到它

  12. 12

    在python中从UDP数据包中删除填充(Linux)

  13. 13

    接收PHP中的UDP数据包数据报

  14. 14

    在PHP中接收UDP数据包数据报

  15. 15

    traceroute中的数据包丢失是速度节流的迹象吗?

  16. 16

    在FreeBSD中不使用ICMP捕获数据包丢失

  17. 17

    如何在Android上运行的Chrome应用中接收UDP广播数据包

  18. 18

    通过广播接收Unity Android应用程序中的UDP数据包

  19. 19

    使用同一套接字发送和接收UDP多播数据包

  20. 20

    监听bash中返回的UDP数据包

  21. 21

    无法在Python中接收UDP数据包

  22. 22

    在Windows 10中发送常规UDP数据包

  23. 23

    在Java中接收UDP而不丢弃数据包

  24. 24

    在Python的CrossbarServer中从Arduino接收UDP数据包

  25. 25

    发送从未收到的多播数据包

  26. 26

    Android BLE通知数据包丢失

  27. 27

    多播时通过WiFi通过UDP丢失数据

  28. 28

    数据包丢失(UDP)的纠错码

  29. 29

    发送UDP数据包似乎会导致不同NIC上的传入数据包丢失

热门标签

归档