MulticastSocket не открывает порт

Я пытаюсь создать простую многоадресную связь между моим ПК (Ubuntu, клиент) и моим телефоном (Android, сервер).

Соединения Unicast/TCP работают без проблем, определенный порт (37659) открывается как на ПК, так и на телефоне. При попытке использовать MulticastSocket порты не открываются. nmap сообщает мне, что указанный порт (36963) является портом TCP и что он закрыт. (Пока выполняется receive-метод).

Я делаю что-то неправильно? Или брандмауэр блокирует многоадресные сокеты? (Я пробовал около 20 разных портов, и ни один из них не работал... в настоящее время используется порт 36963)

EDIT: Также, когда брандмауэр полностью отключен, nmap сообщает мне, что порт закрыт...

Код сервера (телефон):

private void multicastLoop() {
        String res = Build.FINGERPRINT + "\n";
        final InetAddress group;
        final MulticastSocket socket;
        final DatagramPacket response;
        try {
            group = InetAddress.getByName("224.0.0.115");
            socket = new MulticastSocket(mport);
            socket.setLoopbackMode(true);
            socket.setSoTimeout(10000);
            socket.joinGroup(group);
            response = new DatagramPacket(res.getBytes(), res.length(), group, mport);
        } catch (IOException e) {
            e.printStackTrace();
            return;
        }

        Thread t = new Thread(new Runnable() {

            @Override
            public void run() {
                while(isRunning) {
                    try {
                        byte[] data = new byte[1024];
                        DatagramPacket dm = new DatagramPacket(data, data.length);
                        socket.receive(dm);
                        Log.d("udp", "received");
                        if (Arrays.equals(dm.getData(), "someone there".getBytes())) {
                            socket.send(response);
                        }
                    } catch (SocketTimeoutException e) {
                        continue;
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                try {
                    socket.leaveGroup(group);
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        });
        t.start();
    }

Код клиента (компьютер):

public String[] findServers() {
        String hello = "someone there";
        try {
            InetAddress group = InetAddress.getByName(mhost);
            MulticastSocket socket = new MulticastSocket(mport);
            socket.setLoopbackMode(true);
            socket.setSoTimeout(60000);
            socket.joinGroup(group);
            DatagramPacket p = new DatagramPacket(hello.getBytes(), hello.length(), group, mport);
            byte[] buffer = new byte[1024];
            socket.send(p);
            DatagramPacket r = new DatagramPacket(buffer, buffer.length);
            socket.receive(r);
            socket.leaveGroup(group);
            socket.close();
            String srinfo = "";
            byte[] data = r.getData();
            for (byte b: data)
                srinfo += (char) b;
            System.out.println("Server found at " + r.getAddress().getHostName() + ": " + srinfo);
        } catch (SocketTimeoutException e) {
            return new String[] {"timeout"};
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

person s3lph    schedule 16.01.2014    source источник
comment
Итак, тот же код работает на Android/рабочем столе?   -  person turbo    schedule 17.01.2014
comment
Все еще жду разъяснений. У меня есть предложения, если это код Android, но мне недостаточно ясно, что именно вы делаете.   -  person turbo    schedule 17.01.2014
comment
Извините, отсутствовал весь день... Приведенный выше код работает на телефоне. (телефон=сервер). Но клиент (компьютер) не работает   -  person s3lph    schedule 17.01.2014
comment
Ваш код не работает без изменений, потому что вы забыли предоставить какой-то код (кто-то, кто попытается воспроизвести его, потеряет время). Кроме того, имейте в виду, что если вы отправляете мысли в сети Wi-Fi, ожидается потеря пакетов.   -  person Diego C Nascimento    schedule 22.01.2014
comment
Вы используете приведенный выше код на обеих машинах? Если это так, исключение тайм-аута предотвращает отправку ответного пакета, что, я думаю, вам нужно. Поэтому вы должны опубликовать свой другой код и проверить, отправляются и принимаются ли пакеты с помощью анализатора пакетов.   -  person Diego C Nascimento    schedule 22.01.2014
comment
Если вы прочтете мой вопрос, то увидите, что телефон на самом деле ЯВЛЯЕТСЯ сервером. внесу уточнения...   -  person s3lph    schedule 22.01.2014
comment
Вы пробовали .setTimeToLive() вместо .setTimeout()? Я не уверен, однако.   -  person Siva Tumma    schedule 26.01.2014
comment
Что я должен предоставить в качестве аргумента для setTimeToLive()?   -  person s3lph    schedule 26.01.2014
comment
Разобрался, но все равно не работает   -  person s3lph    schedule 27.01.2014


Ответы (2)


Убедитесь, что для mhost установлено значение «224.0.0.115», а не какое-то имя машины.

Убедитесь, что многоадресная рассылка включена на вашем маршрутизаторе.

person Ted Bigham    schedule 25.01.2014
comment
Он установлен на 224.0.0.115. И как роутер влияет на открытие порта на моей машине? Это не работает независимо от того, какой маршрутизатор (включая телефон через точку доступа) я использую - person s3lph; 25.01.2014
comment
Многоадресная рассылка требует взаимодействия вашего сетевого оборудования. Когда вы отправляете многоадресное сообщение, вы не отправляете его на машину, вы отправляете его на свой коммутатор или маршрутизатор, а затем он отправляет его всем, кто его слушает. Вот почему меня немного беспокоит IP-адрес, который вы используете. Он не определен в этом списке en.wikipedia.org/wiki/Multicast_address. Вы пробовали использовать обычный многоадресный адрес 224.0.0.1? - person Ted Bigham; 26.01.2014
comment
Avahi (Zeroconf) тоже использует Multicast и работает без проблем. Таким образом, ни моя сетевая карта не отбрасывает пакеты дейтаграмм, ни маршрутизатор не отказывается от них. Вместо этого использование 224.0.0.1 не работает. - person s3lph; 26.01.2014

  1. Если хост является многосетевым, вам необходимо присоединиться к группе многоадресной рассылки через все локальные интерфейсы, а не только через интерфейс по умолчанию, что вы делаете в настоящее время.

  2. Вы можете отправить ответ обратно на исходный адрес, с которого он пришел, который находится в полученном пакете дейтаграммы. Это также означает, что клиенту не нужен MulticastSocket, а только DatagramSocket.

person user207421    schedule 23.01.2014
comment
Если я правильно понимаю пункт 2, вы хотите, чтобы я позволил СЕРВЕРУ подключиться к источнику DatagramPacket. К пункту 1: Как мне поставить интерфейс? - person s3lph; 23.01.2014
comment
РЕДАКТИРОВАТЬ: я понял это: setNetworkInterface. Но порты по-прежнему закрыты. - person s3lph; 24.01.2014