UDP Packet content changes while transmitting - java

I'm programming an Server-Client Software, where the client connects to the server with an port request, the server opens a new port and sends back the new port number. Then the client communicates with an RSA shared AES key encryption and the port from the port request.
Well, it should be like that.
I had the program already running, only one client could connect to the server, and everything worked fine. But now I'm sending an "portreq" String to the server which should give a port reply. But when i check, if the incoming request is a "portreq" it gives me false. If i do same with .contains it gives me true. That's the first problem, and secondly:
When the server converts the port-Integer into an String and sends it, i can't transform it into a int again on the client-side:
java.lang.NumberFormatException: For input string: "6002������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:580)
at java.lang.Integer.parseInt(Integer.java:615)
at application.PowerPanelController.addDataToCpu(PowerPanelController.java:360)
at application.PowerPanelController.lambda$0(PowerPanelController.java:143)
at application.PowerPanelController$$Lambda$200/357277047.handle(Unknown Source)
at com.sun.scenario.animation.shared.TimelineClipCore.visitKeyFrame(TimelineClipCore.java:226)
at com.sun.scenario.animation.shared.TimelineClipCore.playTo(TimelineClipCore.java:167)
at javafx.animation.Timeline.impl_playTo(Timeline.java:176)
at javafx.animation.AnimationAccessorImpl.playTo(AnimationAccessorImpl.java:39)
at com.sun.scenario.animation.shared.InfiniteClipEnvelope.timePulse(InfiniteClipEnvelope.java:110)
at javafx.animation.Animation.impl_timePulse(Animation.java:1102)
at javafx.animation.Animation$1.lambda$timePulse$25(Animation.java:186)
at javafx.animation.Animation$1$$Lambda$186/1977464318.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at javafx.animation.Animation$1.timePulse(Animation.java:185)
at com.sun.scenario.animation.AbstractMasterTimer.timePulseImpl(AbstractMasterTimer.java:344)
at com.sun.scenario.animation.AbstractMasterTimer$MainLoop.run(AbstractMasterTimer.java:267)
at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:447)
at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:431)
at com.sun.javafx.tk.quantum.QuantumToolkit.lambda$runToolkit$363(QuantumToolkit.java:298)
at com.sun.javafx.tk.quantum.QuantumToolkit$$Lambda$42/317723766.run(Unknown Source)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
Which i don't get because the String looks pretty much the same as i send it.
Here's my client side send and receive function
private String sendCommandNoAES(String command)
{
byte[] outData = new byte[1024];
byte[] inD = new byte[1024];
String message = "";
try
{
// create Socket
DatagramSocket socket = new DatagramSocket();
// build Packet
InetAddress serverIP = InetAddress.getByName(PowerPanelMain.ip);
outData = command.getBytes();
DatagramPacket out = new DatagramPacket(outData,outData.length, serverIP, PowerPanelMain.port); // send packet
socket.send(out);
logger.info("Sent an " + command + " Request non encrypted to " + PowerPanelMain.ip + ":" + PowerPanelMain.port);
// Receive answer
byte[] inData = new byte[1024];
DatagramPacket in = new DatagramPacket(inData,inData.length);
socket.receive(in);
inD = in.getData();
message = new String(inD,0,inD.length);
// Close Socket
socket.close();
logger.info("Go answer " + message + " from " + in.getAddress().toString() + ":" + in.getPort());
}
catch(Exception ee)
{
logger.error("Error while requesting data from server \n" + getStackTrace(ee));
return "offline";
}
return message;
}
This is where i send the portreq:
String portString = sendCommandNoAES("portreq");
int port = Integer.parseInt(portString);
Thats the server code:
byte[] inData = new byte[1024];
byte[] outData = new byte[1024];
String message;
DatagramSocket socket = null;
try
{
socket = new DatagramSocket(port);
System.out.println("Bound to " + port);
//JOptionPane.showMessageDialog(null, "Bound to " + String.valueOf(port), "Yeay", JOptionPane.OK_CANCEL_OPTION);
}
catch(Exception ee)
{
JOptionPane.showMessageDialog(null, "Error occured! \n#002", "Error #002", JOptionPane.OK_CANCEL_OPTION);
}
...
DatagramPacket in = new DatagramPacket(inData,inData.length);
socket.receive(in);
InetAddress senderIP = in.getAddress();
int senderPort = in.getPort();
byte[] inc = in.getData();
message = new String(inc,0,inc.length);
System.out.println("Got " + message + " from " + senderIP + ":" + senderPort + " (byte array: " + inc.toString());
...
if(message.contains("portreq"))
{
System.out.println("Creatinfg answer");
outData = String.valueOf(portcount).getBytes();
DatagramPacket out = new DatagramPacket(outData,outData.length, senderIP, senderPort);
socket.send(out);
System.out.println("Sent " + String.valueOf(portcount));
UDPTraffic udpt = new UDPTraffic(portcount, this.mode);
udpt.start();
portcount++;
}
I'm really thankful to anyone who can solve/explain me why this is happening :D

inD = in.getData();
This merely reasserts the same value. Remove.
message = new String(inD,0,inD.length);
Wrong. You're ignoring the actual length of the received datagram. Change to:
message = new String(in.getData(), in.getOffset(), in.getLength());

You are sending a string of one size, yet on the other side you are reading the string of 1024 bytes - which you never sent. This will not do. You should either serialize string using serialize() method, or, if you want to send raw string bytes, send string length as a separate part of the message.

Related

How to properly compare string values received from datagram packets?

I'm making a simple client server program. When the client sends the string "start", I want the server to start executing some code. Right now, I have the client sending a datagram packet with the message "start", the server gets the byte buffer from the packet, turns it into a string, and then compares that string value with the string literal "start". Obviously I'm doing something wrong because my code never enters the for loop of if(sentence.equals(start){ System.out.println("ok");}
My code:
public static void main(String args[]) throws IOException{
byte[] receiveData;
byte[] sendData;
DatagramSocket serverSocket = new DatagramSocket(2014);
while(true){
receiveData = new byte[15];
DatagramPacket frame = new DatagramPacket(receiveData, receiveData.length);
serverSocket.receive(frame);
InetAddress IPaddress = frame.getAddress();
System.out.println("INET " + IPaddress);
byte[] data;
int port = frame.getPort();
System.out.println("port " + port);
String sentence = new String(frame.getData());
String start = new String("start");
System.out.println("RECEIVED FROM CLIENT: " + sentence);
if(sentence.equals(start)){
System.out.println("ok");
}
}
}
Make the following change.
String sentence = new String(frame.getData(), 0, frame.getLength());

PingIDs (Data) is different on different sides

I am working on a server software for Minecraft: Pocket Edition. Right now I am working on the MOTD for the server, and it works Just fine. When sending a response to a ping packet (0x01) with a 0x1c. It shows up in the world list with the name just fine. But, for some reason, If I send the same data from another program, the Ping ID and ServerID will show different in the consoles. Why is this?
Ping response code:
public PingResponse(DatagramPacket Packet, long ServerID) throws IOException {
// Data from Ping
ByteBuffer ReceivedPing = ByteBuffer.wrap(Packet.getData());
// Set variables
this.ServerID = ServerID;
this.ServerName = ServerPropertiesHandler.getMOTD();
this.PingID = ReceivedPing.getLong();
// Server Name
String Identifier = "MCCPP;MINECON;" + ServerPropertiesHandler.getMOTD();
ByteBuffer PingResponseBuffer = ByteBuffer.allocate(35 + (short) Identifier.length());
// Put Packet ID
PingResponseBuffer.put(PacketIDList.ID_UNCONNECTED_PING_OPEN_CONNECTIONS);
// Ping ID
PingResponseBuffer.putLong(this.PingID);
System.out.println("Ping ID: " + this.PingID);
// Server ID
PingResponseBuffer.putLong(this.ServerID);
System.out.println("Server ID: " + this.ServerID);
// Sugar Spice and everything nice
PingResponseBuffer.put(PacketIDList.MAGIC);
// Server Name
PingResponseBuffer.putShort((short) Identifier.length());
PingResponseBuffer.put(Identifier.getBytes());
// Send
PacketHandler.Socket.send(new DatagramPacket(PingResponseBuffer.array(), PingResponseBuffer.array().length), Packet.getAddress(), Packet.getPort());
}
Client Example:
public static void main(String[] args) {
try {
// SEND
final long PacketID = new Random().nextLong();
DatagramSocket ClientSocket = new DatagramSocket();
ByteBuffer PingBuffer = ByteBuffer.allocate(25);
PingBuffer.put(PacketIDList.ID_CONNECTED_PING_OPEN_CONNECTIONS);
PingBuffer.putLong(PacketID);
PingBuffer.put(PacketIDList.MAGIC);
ClientSocket.send(new DatagramPacket(PingBuffer.array(), PingBuffer.array().length, InetAddress.getByName("localhost"), 19132));
// RECEIVE
byte[] buffer = new byte[1535];
DatagramPacket PongPacket = new DatagramPacket(buffer, buffer.length);
ClientSocket.receive(PongPacket);
byte[] PongPacketData = PongPacket.getData();
ByteBuffer PongBuffer = ByteBuffer.wrap(PongPacketData);
if(PongPacketData[0] == (byte) 0x1c) {
System.out.println("PingID From Server: " + PongBuffer.getLong());
System.out.println("ServerID From Server: " + PongBuffer.getLong());
System.out.println("MAGIC From Server: " + PongBuffer.get());
System.out.println("MOTD From Server: " + PongBuffer.get());
}
else {
System.out.println("UNKNOWN PACKET");
}
ClientSocket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
3 months and no reply. pingID and serverID are identifiers of time used on respective systems to determine the time since start. These provide a double functionality. Firstly, they allow a server to determine any latency in the communications. Secondly, they help provide a packet order to commands. Rebooting a server would generate a new serverID starting from 0, while rejoining a server would provide a new pingID starting at 0.
I would be quite interested to see the progress you've made, as I've begun working on my own.

Connecting to socket to get data from it

I'm trying to connect to a web socket (Details: here ) to get information back from it.
As you can see I need clients IP address and so on, here's what I have so far:
//client IP address
//is client behind something?
String ipAddress = request.getHeader("X-FORWARDED-FOR");
if (ipAddress == null) {
ipAddress = request.getRemoteAddr();
}
String socketAddress = "whois.nic.uk";
int socketPort = 1043;
Socket socket = new Socket(socketAddress, socketPort);
ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
out.flush();
ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
//for every domain loop
String singleDomain = "google.co.uk"; //just an example
//<hostname of client> <IP address of client> <domain to query><cr><lf>
String whoIs2 = ipAddress + " " + ipAddress + " " + singleDomain + "\r\n";
//convert message to bytes
byte[] whoIs2B = whoIs2.getBytes();
Basically I'm not sure how to sent the whoIs2B (byte version to the socket if that makes sense?). I then need to change the byte response to text, that's all I need.
Note: Don't mind try / catches since I had to delete some unnecessary info to make it easier to see what I'm asking.
To send the bytes down the socket you need to write to the underlying stream 'out'.
You'd do something similar for the input stream.
http://docs.oracle.com/javase/tutorial/networking/sockets

java.lang.NumberFormatException: null in Integer.parseInt

Okay, the following are 2 classes that I am using in creating a simple TFTP (Trivial File Transfer Protocol) program. I am running a server instance and a client instance of this program. What I am trying to accomplish is this:
The client connects to the server and sends a message of a specific file that it wants. The server locates the file and sends a response (either a 1 or 0... 1 meaning the file is there, and 0 meaning that it is not). Then the server will send the content of the file to the client application. The files I am trying to send are just simple text files.
Right now, I am able to receive the name of the text file that the client wants, but then when I go to send back the response, I am not getting anything returned. Also below are the methods that the server and the client both run.
This is the server instance
SwingUtilities.invokeLater(new Runnable(){
public void run(){
String fileRequest = UDPReceiver(SERVER_PORT_NUMBER);
outputArea.append("\n" + "File Requested: " + fileRequest + "\n");
outputArea.append("Determining if file exists...\n");
String checkFile = SHARED_DIR + "\\" + fileRequest;
outputArea.append("Checking location: " + checkFile + "\n");
boolean check = fileCheck(checkFile);
if(check == true){
outputArea.append("File location verified..." + "\n");
outputArea.append("Initiating transfer...." + "\n\n");
UDPSender(CLIENT_HOSTNAME, CLIENT_PORT_NUMBER, "1");
}
else{
outputArea.append("File does not exist..." + "\n");
outputArea.append("Exiting run..." + "\n");
}
}
});
The client instance.
SwingUtilities.invokeLater(new Runnable(){
public void run(){
UDPSender(SERVER_HOSTNAME, SERVER_PORT_NUMBER, FILE_REQUEST);
String message = UDPReceiver(CLIENT_PORT_NUMBER);
outputArea.append("\n\n" + message + "\n");
if(message == "1"){
// File exists
outputArea.append("\n");
outputArea.append("File verified..." + "\n");
outputArea.append("Transfer initiated..." + "\n");
}
else{
// File doesn't exist
outputArea.append("\n");
outputArea.append("File does not exist..." + "\n");
outputArea.append("Terminating connection...");
}
}
});
Here are the Sender and Receiver methods.
private void UDPSender(String hostname, String port, String message){
DatagramSocket socket = null;
try{
// Create a datagram socket, look for the first available port
socket = new DatagramSocket();
outputArea.append("Using local port: " + socket.getLocalPort() + "\n");
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
PrintStream pOut = new PrintStream(bOut);
pOut.print(message);
// Convert printstream to byte array
byte[] bArray = bOut.toByteArray();
// Create a DatagramPacket, containing a maximum buffer of 256 bytes
DatagramPacket packet = new DatagramPacket(bArray, bArray.length);
outputArea.append("Looking for hostname " + hostname + "\n");
// Get the InetAddress object
InetAddress remote_addr = InetAddress.getByName(hostname);
// Check its IP Number
outputArea.append("Hostname has IP Address = " + remote_addr.getHostAddress() + "\n");
// Configure the DatagramPacket
packet.setAddress(remote_addr);
packet.setPort(Integer.parseInt(port));
// Send the packet
socket.send(packet);
outputArea.append("Packet sent at: " + new Date() + "\n");
// Display packet information
outputArea.append("Sent by: " + remote_addr.getHostAddress() + "\n");
outputArea.append("Sent from: " + packet.getPort() + "\n");
socket.close();
}
catch(UnknownHostException ue){
outputArea.append("Unknown host: " + hostname + "\n");
outputArea.append("Unknown host: " + ue + "\n");
}
catch(IOException e){
outputArea.append("Error: " + e + "\n");
}
}
private String UDPReceiver(String portNum){
String message = "";
DatagramSocket socket = null;
try{
// Create a DatagramSocket
socket = new DatagramSocket(Integer.parseInt(portNum));
outputArea.append("Listening on local port " + socket.getLocalPort() + "\n");
// Create a DatagramPacket, containing a maximum buffer of 256 bytes
DatagramPacket packet = new DatagramPacket(new byte[256], 256);
// Receive a packet - remember by default this is a blocking operation
socket.receive(packet);
outputArea.append("Packet received at " + new Date() + "\n");
// Display packet information
InetAddress remote_addr = packet.getAddress();
outputArea.append("Sender: " + remote_addr.getHostAddress() + "\n");
outputArea.append("From Port: " + packet.getPort() + "\n");
CLIENT_HOSTNAME = remote_addr.getHostAddress();
//CLIENT_PORT_NUMBER = Integer.toString(packet.getPort());
// Display packet contents, by reading from byte array
ByteArrayInputStream bin = new ByteArrayInputStream(packet.getData());
// Display only up to the length of the original UDP packet
for(int i = 0; i < packet.getLength(); i++){
int data = bin.read();
if(data == -1){
break;
}
else{
message = message + (char)data;
//outputArea.append(Character.toString((char)data));
}
}
socket.close();
return message;
}
catch(IOException e){
outputArea.append("Error: " + e + "\n");
message = "Error: " + e;
return message;
}
}
Any help that you folks can offer would be greatly appreciated. The main thing I am trying to figure out is how to be able to get the server and client to be able to send messages back and forth. Thanks in advance guys.
EDIT:
I am also getting an error now in Netbeans when I run this project. I think it has something to do with this line of code in the UDPReceiver method:
socket = new DatagramSocket(Integer.parseInt(portNum));
But I can't figure out what is wrong with that.
Exception in thread "AWT-EventQueue-0" java.lang.NumberFormatException: null
at java.lang.Integer.parseInt(Integer.java:454)
at java.lang.Integer.parseInt(Integer.java:527)
at tftp_gui.main.UDPReceiver(main.java:508)
at tftp_gui.main.access$800(main.java:20)
at tftp_gui.main$10.run(main.java:374)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:721)
at java.awt.EventQueue.access$200(EventQueue.java:103)
at java.awt.EventQueue$3.run(EventQueue.java:682)
at java.awt.EventQueue$3.run(EventQueue.java:680)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:691)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:244)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:163)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:151)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:147)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:139)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:97)
you approach is wrong, as it is requires opened client port, anyway your particular problem is because you're not sending back result when file is not found:
check:
if(check == true){
outputArea.append("File location verified..." + "\n");
outputArea.append("Initiating transfer...." + "\n\n");
UDPSender(CLIENT_HOSTNAME, CLIENT_PORT_NUMBER, "1");
}
else {
outputArea.append("File does not exist..." + "\n");
outputArea.append("Exiting run..." + "\n");
UDPSender(CLIENT_HOSTNAME, CLIENT_PORT_NUMBER, "0"); // here you should send 0
}
also, you have small problem here: if(message == "1") it should look like if ("1".equals(message))
Your error is self explainable - you're haven't declared proper CLIENT_PORT_NUMBER or SERVER_PORT_NUMBER, here is what I've used for testing:
private final static String SERVER_PORT_NUMBER = "1234";
private static String CLIENT_HOSTNAME;
private static final String CLIENT_PORT_NUMBER = "2345";
private static final String FILE_REQUEST = "a.txt";
private static final String SHARED_DIR = "d:/";
private static final String SERVER_HOSTNAME = "localhost";

UDP Broadcast in Java

Morning.
I'm pretty new in Java and socket connections but I'm trying to send out a UDP packet/broadcast on 255.255.255.255 on port 8001 to a device. I can get the data to send just fine, however when it comes time to receive the data the connection times out. I have a packet sniffer and I can see the packet send and then the device respond.
I'm pretty sure it is a rookie mistake that I'm missing in my code but I've been stuck on it for awhile and any help would be appreciated.
m_Socket = new DatagramSocket(m_SERVERPORT);
InetAddress address = InetAddress.getByName(m_SERVERIP);
m_DataPack = new DatagramPacket(m_SERVERCMD.getBytes(), m_SERVERCMD.getBytes().length,
address, m_SERVERPORT);
m_Socket.setBroadcast(true);
m_Socket.connect(address, m_SERVERPORT);
m_Socket.send(m_DataPack);
m_DataPack = new DatagramPacket(data, data.length,
address, m_SERVERPORT);
m_Socket.receive(m_DataPack); // This is where it times out
data = m_DataPack.getData();
String received = data.toString();
System.out.println("Received: " + received);
m_Socket.close();
Thanks and Gig'Em.
EDIT:
I'm not sure if this helps but when I watch the m_Socket object I can see the following right before it sends:
bound = true;
close = false;
connectedAddress = Inet4Address (id = 32) (-1,-1,-1,-1);
connectedPort = 8001;
connectState = 1;
created = true;
impl = PlainDatagramSocketImpl;
oldImpl = false;
and the m_DataPack object is the following:
address = Inet4Address (id = 32) (-1,-1,-1,-1);
bufLength = 6 (size of packet I'm sending is 6 char long);
offset = 0;
port = 8001;
This doesn't make sense. You are broadcasting, which is 1-to-many, and you are also connecting, which is 1-to-1. Which is it?
Lose the connect. And lose the 255.255.255.255. This has been heavily deprecated for about 20 years. Use a subnet-local broadcast address, e.g. 192.168.1.255.
You can also take a look at MulticastSocket described at Broadcasting to Multiple Recipients. Hope this helps.
If you want to receive a datagram you need to bind() to the local endpoint (address + port).
You are sending and receiving the packet on same device. You could separate send and receive ports (e.g send on 8001, receive on 8002). And run send and receive codes as separate threads. If both device must find each other (or one device find itself).
import java.io.IOException;
import java.net.*;
Receiving:
private DatagramSocket getReceiveSocket() throws UnknownHostException, SocketException {
if (receiveSocket == null) {
receiveSocket = new DatagramSocket(8002, InetAddress.getByName("0.0.0.0")); // 0.0.0.0 for listen to all ips
receiveSocket.setBroadcast(true);
}
return receiveSocket;
}
public void receive() throws IOException {
// Discovery request command
byte[] buffer = "__DISCOVERY_REQUEST__".getBytes();
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
getReceiveSocket().receive(packet);
System.out.println("Discovery package received! -> " + packet.getAddress() + ":" + packet.getPort());
// Get received data
String data = new String(packet.getData()).trim();
if (data.equals("__DISCOVERY_REQUEST__")) { // validate command
// Send response
byte[] response = new byte["__DISCOVERY_RESPONSE".length()];
DatagramPacket responsePacket = new DatagramPacket(response, response.length, packet.getAddress(), packet.getPort());
getReceiveSocket().send(responsePacket);
System.out.println("Response sent to: " + packet.getAddress() + ":" + packet.getPort());
} else {
System.err.println("Error, not valid package!" + packet.getAddress() + ":" + packet.getPort());
}
}
Sending:
private DatagramSocket getSendSocket() throws UnknownHostException, SocketException {
if (sendSocket == null) {
sendSocket = new DatagramSocket(8001, InetAddress.getLocalHost());
sendSocket.setBroadcast(true);
}
return sendSocket;
}
public void send() throws IOException {
// Discovery request command
byte[] data = "__DISCOVERY_REQUEST__".getBytes();
DatagramPacket packet = new DatagramPacket(data, data.length, InetAddress.getByName("255.255.255.255"), 8002);
getSendSocket().send(packet);
System.out.println("Discovery package sent!" + packet.getAddress() + ":" + packet.getPort());
// Discovery response command
byte[] response = new byte["__DISCOVERY_RESPONSE__".length()];
DatagramPacket responsePacket = new DatagramPacket(response, response.length);
getSendSocket().receive(responsePacket);
System.out.println("Discovery response received!" + responsePacket.getAddress() + ":" + responsePacket.getPort());
String responseData = new String(responsePacket.getData()).trim();
if (responseData.equals("__DISCOVERY_RESPONSE__")) { // Check valid command
System.out.println("Found buddy!" + responsePacket.getAddress() + ":" + responsePacket.getPort());
}
}
Of course should put this code in a loop in a thread.
Based on this example: https://demey.io/network-discovery-using-udp-broadcast/
UPDATE
The link above is dead. But same method described here also: https://www.baeldung.com/java-broadcast-multicast

Categories