简体   繁体   中英

UDP Multicast with Java: Message cannot be received by entire multicast group

I am trying to understand how multicast works, thus I am experimenting with it a bit.

Situation

I built a simple server which has a MulticastSocket , listening on port 1250. It simply echoes the message it receives.

Next I built a simple client, also with a MulticastSocket , listening on port 4711. It sends a String-Message to the server and waits for any message that comes back.

Expected behaviour

I want two or more clients send their own unique message to the server and receive all responses the server sends back to the multicast group listening on port 4711.

Observed behaviour / Problem

As soon as I start more than one instance of the client, all responses from the server are only received by the first client that joined the group. All other clients that joined the multicast group on port 4711 do not receive anything. Why is this and how can I solve the problem?

The result looks like this (you can see that only the process MulticastEchoClient2 receives the server's response):

组播EchoServer组播EchoClient1组播EchoClient2

Code

Server-Code

public class MulticastEchoServer
{
    public static void main(String[] args)
    {
        if (args.length != 2)
        {
            System.out.println("Wrong usage of parameters! <MulticastAddress><id>");
            return;
        }

        UDPMulticastSocket socket = null;
        String id = args[1];

        try
        {
            socket = new UDPMulticastSocket(1250);
            System.out.println("Socket created...");

            socket.join(args[0]);

            while(true)
            {
                String msg = socket.receive(1024);
                System.out.println("Message received: " + msg + " from " + socket.getSenderAddress() + ":" + socket.getSenderPort());

                if (msg.toLowerCase().equals("quit"))
                {
                    System.out.println("Shutting down...");
                    break;
                }

                socket.reply("Reply from " + id + " -> " + msg);
            }

            socket.leave(args[0]);
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }

        if (socket != null)
        {
            socket.close();
            System.out.println("Shutting down...");
        }
    }
}

Client Code

public class MulticastEchoClient
{
    public final static int MESSAGES = 10000;

    public static void main(String[] args)
    {
        if (args.length != 3)
        {
            System.out.println("Wrong usage of parameters: <Multicast-Address><Address of Server><id>");
            return;
        }

        UDPMulticastSocket socket = null;
        String id = args[2];

        try
        {
            socket = new UDPMulticastSocket(4711);
            socket.setTimeout(1000);
            System.out.println("Socket created...");

            socket.join(args[0]);
            InetAddress srvrAddress = InetAddress.getByName(args[1]);

            for (int i = 0; i < MESSAGES; i++)
            {
                socket.send(id + " sending: " + i, srvrAddress, 1250);

                try
                {
                    while(true)
                    {
                        String msg = socket.receive(1024);
                        System.out.println("Message received: " + msg + " from " + socket.getSenderAddress() + ":" + socket.getSenderPort());
                    }
                }
                catch (IOException e)
                {
                    System.out.println("All messages received...");
                }
            }

            socket.leave(args[0]);
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }

        if (socket != null)
        {
            socket.close();
            System.out.println("Shutting down...");
        }
    }
}

Utility Classes

public class UDPSocket
{
    protected DatagramSocket socket;
    private InetAddress senderAddress;
    private int senderPort;

    //constructors
    protected UDPSocket(DatagramSocket socket)
    {
        this.socket = socket;
    }

    public UDPSocket() throws SocketException
    {
        this(new DatagramSocket());
    }

    public UDPSocket(int port) throws SocketException
    {
        this(new DatagramSocket(port));
    }

    //getters
    public InetAddress getSenderAddress()
    {
        return senderAddress;
    }

    public int getSenderPort()
    {
        return senderPort;
    }

    //setters
    public void setTimeout(int timeout) throws SocketException
    {
        socket.setSoTimeout(timeout);
    }

    //methods
    public void send(String s, InetAddress rcvrAddress, int rcvrPort) throws IOException
    {
        byte[] data = s.getBytes();
        DatagramPacket outPacket = new DatagramPacket(data, 0, data.length, rcvrAddress, rcvrPort);

        socket.send(outPacket);
    }

    public String receive(int maxBytes) throws IOException
    {
        byte[] data = new byte[maxBytes];
        DatagramPacket inPacket = new DatagramPacket(data, 0, data.length);
        socket.receive(inPacket);

        senderAddress = inPacket.getAddress();
        senderPort = inPacket.getPort();

        //return new String(data, 0, data.length);
        return new String(data, 0, inPacket.getLength());
    }

    public void reply(String s) throws IOException
    {
        if (senderAddress != null)
        {
            send(s, senderAddress, senderPort);
        }
        else
        {
            throw new IOException("ERROR: No one to reply to!");
        }
    }

    public void close()
    {
        socket.close();
    }
}

public class UDPMulticastSocket extends UDPSocket
{
    public UDPMulticastSocket(int port) throws IOException
    {
        super(new MulticastSocket(port));
    }

    public UDPMulticastSocket() throws IOException
    {
        super(new MulticastSocket());
    }

    public void join(String mcAddress) throws IOException
    {
        InetAddress ia = InetAddress.getByName(mcAddress);
        ((MulticastSocket) socket).joinGroup(ia);
    }

    public void leave(String mcAddress) throws IOException
    {
        InetAddress ia = InetAddress.getByName(mcAddress);
        ((MulticastSocket) socket).leaveGroup(ia);
    }
}

You're replying to the sending address, so only the sending address is receiving the reply. If you want to reply to the multicast group, reply to the multicast group, not the sending address.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM