4 Stimmen

Wie man Multicasting in einem System mit mehreren Netzwerkverbindungen (Java, Linux) verwendet

Dies ist in Java, aber ich kann immer zu C über JNI zurückkehren, wenn nötig.

Ich habe ein System mit zwei NICs, die jeweils mit einem eigenen Subnetz verbunden sind. Ich möchte Multicast (insbesondere SDP) verwenden, um andere Hosts in beiden Netzwerken zu entdecken.

Ein Netzwerk ist einfach: Erstellen Sie einen MulticastSocket auf dem angegebenen Port, treten Sie der Gruppe bei und ich erhalte Pakete. Einfachheit.

Zwei Netzwerke: bisher unmöglich. Ich habe versucht:

1) zwei Sockets zu erstellen, die an denselben Port gebunden sind, und mit setInterface () oder setNetworkInterface () "verbinden", um mit dem richtigen Interface zu "verbinden". Kein Glück, auch nach verschiedenen Permutationen von setReuseAddress ().

2) Erstellen Sie einen einzelnen Socket und versuchen Sie dann, zweimal beizutreten, mit zwei Aufrufen von joinGroup (SocketAddress mcastaddr, NetworkInterface netIf). Der zweite Beitreten-Aufruf schlägt fehl.

Lösungen außerhalb von Java wären großartig. Insbesondere, wenn ich Multicast-Routen einrichten könnte, die die beiden Schnittstellen effektiv 'kombinieren' (dann könnte ich jedes Paket untersuchen, um zu bestimmen, welches Netzwerk) das wäre in Ordnung. Wie ich bereits erwähnte, ist jede Menge nativer Code in dieser Umgebung verwendbar (Linux, mit der Apache "luni" Java-Infrastruktur).

Danke!

8voto

Zufällig habe ich vor kurzem an einem ähnlichen Problem gearbeitet.

Hier ist etwas Java-Code, der tut, was du willst - er nimmt SDP-Pakete auf mehreren Schnittstellen auf. joinGroup wird verwendet, um sich mit den angegebenen Schnittstellen zu "verbinden".

/**
 * Demonstriere das Empfangen von Multicast auf mehreren Netzwerkschnittstellen
 *
 * Verwendung: java Multihome eth0 eth1 lo 
 */

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
importjava.net.InetSocketAddress;
import java.net.MulticastSocket;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;

public class Multihome {
    // SDP-Konstanten
    public static final String MULTICAST_ADDRESS = "239.255.255.250";
    public static final int MULTICAST_PORT = 1900;

    // args: Jedes Argument ist der Name einer Netzwerkschnittstelle.
    public void doMain(Set args)
            throws Exception
    {
        InetSocketAddress socketAddress = new InetSocketAddress(MULTICAST_ADDRESS, MULTICAST_PORT);
        MulticastSocket socket = new MulticastSocket(MULTICAST_PORT);
        Enumeration ifs = NetworkInterface.getNetworkInterfaces();

        while (ifs.hasMoreElements()) {
            NetworkInterface xface = ifs.nextElement();
            Enumeration addrs = xface.getInetAddresses();
            String name = xface.getName();

            while (addrs.hasMoreElements()) {
                InetAddress addr = addrs.nextElement();
                System.out.println(name + " ... hat Adresse " + addr);
            }

            if (args.contains(name)) {
                System.out.println("Füge " + name + " zu unserer Schnittstellengruppe hinzu");
                socket.joinGroup(socketAddress, xface);
            }
        }

        byte[] buffer = new byte[1500];
        DatagramPacket packet = new DatagramPacket(buffer, buffer.length);

        while (true) {
            try {
                packet.setData(buffer, 0, buffer.length);
                socket.receive(packet);
                System.out.println("Paket von " + packet.getAddress() + " mit Länge " + packet.getLength() + " erhalten");
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }

    public static void main(String[] args)
            throws Exception
    {
        Set argSet = new HashSet();
        Multihome multi = new Multihome();

        for (String arg : args) {
            argSet.add(arg);
        }

        multi.doMain(argSet);
    }
}

2voto

Jonathan Feinberg Punkte 43293

Ich würde empfehlen, JGroups zu verwenden, das alles abstrahiert, was Sie zu tun versuchen, wenn ich Ihre Bedürfnisse richtig verstehe. Es ist ein elegantes und gut gemachtes Framework für Multicast (und multicast-ähnliche Semantik, nachgebildet, wenn nötig).

0voto

jarnbjo Punkte 33136

Ich habe hier kein vernünftiges Setup, um dies auszuprobieren, aber der Empfang von Multicast-Nachrichten sollte nicht erfordern, dass der MulticastSocket an die Portnummer von der Multicast-Adresse gebunden ist und setNetworkInterface verwendet wird, um das Interface für ausgehende Nachrichten festzulegen.

Was ich versuchen würde, ist zwei verschiedene MulticastSockets (auf einem beliebigen freien Port) zu erstellen und dann joinGroup(SocketAddress mcastaddr, NetworkInterface netIf) für jeden von ihnen unter Verwendung derselben Multicast-Adresse, aber unterschiedlichen Netzwerkschnittstellen zu verwenden.

0voto

Hast du überlegt, ZeroConf dafür zu verwenden?

Das jmdns Projekt hat eine reine Java-Implementierung, die sehr gut funktionieren sollte.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X