Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/231.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Android上DatagramSocket的send()中存在奇怪的块_Java_Android_Sockets_Udp_Blocking - Fatal编程技术网

Java Android上DatagramSocket的send()中存在奇怪的块

Java Android上DatagramSocket的send()中存在奇怪的块,java,android,sockets,udp,blocking,Java,Android,Sockets,Udp,Blocking,我正在尝试在Android手机上向家庭网络中的每个可能的主机发送UDP数据包。好吧,发送UDP数据包很少会阻塞,但当我在两部Android M手机上运行这个程序时,它总是阻塞一次大约2秒钟。有时,它会在第183次send(),有时在第237次send(),它会随着路由器的变化而变化,我用Netgear路由器、谷歌wifi等进行测试。我知道我可以将UDP数据包发送到广播地址,如192.168.1.255,这不是我想要的。代码如下: MainActivity.java package com.exa

我正在尝试在Android手机上向家庭网络中的每个可能的主机发送UDP数据包。好吧,发送UDP数据包很少会阻塞,但当我在两部Android M手机上运行这个程序时,它总是阻塞一次大约2秒钟。有时,它会在第183次
send()
,有时在第237次
send()
,它会随着路由器的变化而变化,我用Netgear路由器、谷歌wifi等进行测试。我知道我可以将UDP数据包发送到广播地址,如
192.168.1.255
,这不是我想要的。代码如下:

MainActivity.java

package com.example.udp;

// import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;

import java.math.BigInteger;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class MainActivity extends AppCompatActivity {

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

//    private class MyTask extends AsyncTask<UDPSender, Void, Void> {
//        @Override
//        protected Void doInBackground(UDPSender... params) {
//            // change it to your CIDR
//            for (InetAddress addr: ipList("10.1.1.0/24")) {
//                params[0].send(addr);
//            }
//            return null;
//        }
//    }

    public void send(View view) {
        final UDPSender sender = new UDPSender();
//        MyTask task = new MyTask(); // AsyncTask doesn't work too.
//        task.execute(sender);
        ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
        executor.scheduleWithFixedDelay(new Runnable() {
            int i = 0;
            // change it to your CIDR
            ArrayList<InetAddress> ips = ipList("10.0.0.0/24");
            @Override
            public void run() {
                if (i < ips.size()) {
                    sender.send(ips.get(i));
                    i++;
                }
            }
        }, 0, 10, TimeUnit.MILLISECONDS);
    }

    private ArrayList<InetAddress> ipList(String cidr) {
        ArrayList<InetAddress> ipList = new ArrayList<>();
        String[] ipnet = cidr.split("/");
        int hostBits = 32 - Integer.parseInt(ipnet[1]);
        // If a literal IP address is supplied, only the
        // validity of the address format is checked.
        try {
            InetAddress addr = InetAddress.getByName(ipnet[0]);
            int ip = new BigInteger(addr.getAddress()).intValue();

            int start = (ip >> hostBits) << hostBits;
            int end = ip | ((1 << hostBits) - 1);

            for (int i = start + 1; i < end; i++) {
                if (i != ip) { // exclude itself
                    InetAddress inetAddress = InetAddress.getByAddress(BigInteger.valueOf(i).toByteArray());
                    ipList.add(inetAddress);
                }
            }
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }

        return ipList;
    }
}
布局只包含一个触发发送的按钮,这与此行为无关。交通太多会导致这种情况吗?有没有办法避免这种情况?我应该求助于NIO吗

更新:
我在安卓N手机上测试了这个应用程序,它不会阻塞

package com.example.udp;


import android.util.Log;

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

public class UDPSender {
    private final static String TAG = "UDPSender";
    private final static int PORT = 4000;
    private static byte[] PKT = "hello".getBytes();
    private DatagramSocket dgram;
    private Thread thread;
    public UDPSender() {
        try {
            this.dgram = new DatagramSocket();
            this.dgram.setSoTimeout(200);
        } catch (IOException e) {
            Log.e(TAG, e.getMessage());
        }
        this.thread = new Thread(new Runnable() {
            @Override
            public void run() {
                byte[] bArr = new byte[1024];
                while (true) {
                    DatagramPacket datagramPacket = new DatagramPacket(bArr, 1024);
                    try {
                        dgram.receive(datagramPacket);
                        Log.d(TAG, "recv something from" + datagramPacket.getAddress().toString());
                    } catch (Exception e) {

                    }
                }
            }
        });
        this.thread.start();
    }

    public void send(InetAddress addr) {
        try {
            long startTime = System.currentTimeMillis();
            this.dgram.send(new DatagramPacket(PKT, PKT.length, addr, PORT));
            long endTime = System.currentTimeMillis();
            Log.d(TAG, "send to " + addr.toString() + " " + (endTime - startTime) + " milliseconds");
        }catch (Exception e) {
            Log.d(TAG, e.toString());
        }
    }
}