Android多播 - 有时接收是阻塞线程

时间:2012-07-16 21:14:13

标签: java android networking network-programming multicast

我相信MulticastSocket.receive方法阻止了我的线程。除非应用程序转到重新启动线程的onResume(),否则它将无法再次工作。我该如何解决这个问题?

接收者代码

private class ReceiverThread extends Thread
{

    private static final String TAG = ComMessageReceiver.TAG + "Thread";

    private WifiManager wifiManager;
    private MulticastSocket multicastSocket;
    private InetSocketAddress groupInetSocketAddress;
    private boolean joinedGroup = false;

    public ReceiverThread(String group, int port, int timeout) throws IOException {

        super();

        wifiManager = (WifiManager) App.context.getSystemService(Context.WIFI_SERVICE);
        groupInetSocketAddress = new InetSocketAddress(InetAddress.getByName(group), port);
        multicastSocket = new MulticastSocket(port);
        multicastSocket.setSoTimeout(timeout);
    }

    public ReceiverThread() throws IOException {

        this(Config.multicastAddress, Config.multicastPort, DEFAULT_TIMEOUT);
    }

    @Override
    public void run() {

        Log.d(TAG, "started");

        while (!this.isInterrupted()) {

            if (wifiManager.getWifiState() == WifiManager.WIFI_STATE_ENABLED) {

                if (!joinedGroup) {

                    try {
                        multicastSocket.joinGroup(groupInetSocketAddress,
                                NetworkInterface.getByInetAddress(getWifiInetAddress()));

                        wifiManager.createMulticastLock("ComMessageReceiverLock").acquire();

                        joinedGroup = true;

                    } catch (IOException ex) {

                        Log.e(TAG, "Failed to join Multicast group: " + ex.getMessage());
                    }
                }

                try {

                    byte[] buffer = new byte[256];

                    DatagramPacket packet = new DatagramPacket(buffer, buffer.length);

                    multicastSocket.receive(packet);

                    Log.d(TAG, "Message received: " + message.message);

                } catch (SocketTimeoutException e) {
                } catch (IOException ex) {

                    multicastSocket = null;

                    Log.e(TAG, ex.getMessage());
                }
            } else
                joinedGroup = false;
        }
    }

}

多播代码

private class ComServerThread extends Thread {

    private static final String LOG = "ComServerThread";
    private final static long INTERVAL = 1000;
    private boolean alert = true;

    private DatagramSocket socket;

    public ComServerThread() {

        try {

            socket = new DatagramSocket(5500);
        } catch (SocketException ex) {

            Log.e(LOG, "Error opening socket: " + ex.getMessage());
        }
    }

    @Override
    public void run() {

        while (!this.isInterrupted()) {

            try {

                try {

                    sleep(INTERVAL);
                } catch (InterruptedException ex) {

                    Log.e(LOG, "Interrupted the thread sleep! not cool: "
                            + ex.getMessage());
                }

                byte[] buffer;

                String msg = "Test"

                buffer = msg.getBytes();

                InetAddress group = InetAddress.getByName("230.0.0.1");

                DatagramPacket packet = new DatagramPacket(buffer,
                        buffer.length, group, 5500);
                socket.send(packet);

                Log.d(LOG, "Packet sent.");

            } catch (UnknownHostException ex) {

                Log.e(LOG, "Oops. Invalid host: " + ex.getMessage());
            } catch (IOException ex) {

                Log.e(LOG,
                        "Something bad happened while sending the packet. Take a look: "
                                + ex.getMessage());
            }
        }
    }
}

1 个答案:

答案 0 :(得分:2)

你是对的,这是一种阻止方法。

如果你设置了一个读取超时,它会抛出你似乎忽略的SocketTimeoutException,,所以你的代码只会循环并阻塞。

每次循环时都不需要加入组播组:这只是浪费。