我试图理解多播是如何工作的,因此我正在试验它。
场合
我构建了一个简单的服务器,其中有MulticastSocket
,侦听端口1250.它只是回显它收到的消息。
接下来我构建了一个简单的客户端,同时使用MulticastSocket
,侦听端口4711.它向服务器发送一个String-Message并等待返回的任何消息。
预期行为
我希望两个或更多客户端向服务器发送自己唯一的消息,并接收服务器发送回端口4711上侦听的多播组的所有响应。
观察到的行为/问题
只要我启动客户端的多个实例,服务器的所有响应都只能由加入该组的第一个客户端接收。在端口4711上加入多播组的所有其他客户端都不会收到任何内容。为什么这样,我该如何解决这个问题?
结果如下(您可以看到只有进程 MulticastEchoClient2 收到服务器的响应):
代码
服务器的代码
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...");
}
}
}
客户代码
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...");
}
}
}
实用程序类
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);
}
}
答案 0 :(得分:2)
您正在回复发送地址,因此只有发送地址才会收到回复。如果要回复组播组,请回复组播组,而不是发送地址。