4

Androidで極端なUDP パケット損失が発生していますが、意味がありません。状況は次のとおりです。

  1. ホームネットワークに接続されたJavaクライアントを実行しているPC
  2. ホームネットワークに接続されたJavaサーバー(Android)を実行している電話
  3. ホームルーターは新品のWRT1900acです。ネットワークにはインターネット接続があります。
  4. UDP パケットが小さい (< 15 バイト)

症状:

  1. PC が UDP パケットを別の PC (両方とも同じネットワーク上) に送信すると、非常にうまく機能します (ほとんどパケットが失われません)。

  2. Android が UDP パケットを同じネットワーク上の PC に送信する場合も、非常にうまく機能します (パケットの損失はほとんどありません)。

  3. PC が同じネットワーク上の Android に UDP を送信すると、極端なパケット損失が発生します (50% 以上の確率ですが、状況によって異なります)。

ほとんどの場合、パケットを 1 回通過させるのに 10 回ほどパケットを送信する必要があります。それ以外の場合は、かなりの遅延が発生します。Androidの受信側でのみ発生する非常に奇妙な動作。Android を Java で同じコードを実行する PCに置き換えるか、Packet Sender の UDP サーバーを介してパケットを受信するだけであれば、損失の問題はありません。私が気付いたもう 1 つのことは、ルーターを経由する代わりに、インターネットに接続されていない、または他のクライアントが存在しない別のアクセス ポイントを経由すると、パフォーマンスが劇的に向上するように見えることです。これは予想されることですが、私の質問は、なぜ Android の受信側のパフォーマンスがこれほど低いのかということです。非常に多くのパケットを失います。Android が、同じコードを実行し、同じネットワーク上で実行されている別の PC に置き換えられた場合、問題はありません。Androidまた、パケットの送信に問題はありません(パケットが失われることはありません)。したがって、受信側でAndroidに関連する何かでなければなりません...

また、PC コードを Packet Sender に置き換えてみましたが、同じ結果が得られました。問題は Android の受信側にあるようです。PC側とAndroidで同じUDPコードを実行します。

UDP 送信コードは単純です。

public void sendMessage(String message)
{
    try {
        DatagramSocket ds = new DatagramSocket();
        DatagramPacket dp;
        InetAddress local = InetAddress.getByName(ipPool);
        dp = new DatagramPacket(message.getBytes(), message.length(), local, port);
        ds.setBroadcast(true);
        ds.send(dp);
        ds.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

Android の UDP 受信コードは、UDP サーバー クラスに存在します。

public class UDP_Server
{
    CommandParser commandParser;

    public UDP_Server(MainActivity mainActivity)
    {
        Log.i("Udp tutorial", "---------------------------Starting UDP SERVER");

        commandParser = new CommandParser(mainActivity);
        String text;
        int server_port = 9876;
        try
        {
            DatagramSocket s = new DatagramSocket(server_port);
            s.setBroadcast(true);
            //s.setReceiveBufferSize(163840);


            while (true)
            {
                byte[] message = new byte[1024];
                DatagramPacket p = new DatagramPacket(message, message.length);

                s.receive(p);
                text = new String(message, 0, p.getLength());
                Log.d("Udp tutorial","message:" + text);
                //commandParser.parseCommand(text);
                //s.close();
            }
        } catch (SocketException e)
        {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

UDPServer.java クラスは、メイン アクティビティの「onCreate()」メソッドによってインスタンス化されます。

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
        StrictMode.setThreadPolicy(policy);

        wm = (WifiManager) getSystemService(WIFI_SERVICE);

        Log.i("Udp tutorial", "---------------------------HERE 1");
        Thread thread = new Thread(new Runnable()
        {
            public void run()
            {
                UDP_Server svr = new UDP_Server(MainActivity.this);
            }
        });

        thread.setPriority(Thread.MAX_PRIORITY);
        thread.start();
//        TCPServer server = new TCPServer();
    }
4

1 に答える 1