简体   繁体   English

使用Java的UDP组播:整个组播组无法接收消息

[英]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. 我建立了一个简单的服务器,该服务器具有一个MulticastSocket ,侦听端口1250。它只是回显收到的消息。

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. 接下来,我构建了一个简单的客户端,该客户端也带有MulticastSocket ,侦听端口4711。它将客户端发送String-Message到服务器,并等待返回的任何消息。

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. 我希望两个或多个客户端将自己的唯一消息发送到服务器,并接收服务器发送回侦听端口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. 在端口4711上加入多播组的所有其他客户端都不会收到任何信息。 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): 结果如下所示(您可以看到只有进程MulticastEchoClient2接收到服务器的响应):

组播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. 如果要答复多播组,请答复多播组,而不是发送地址。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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