diff --git a/core-java/src/main/java/com/baeldung/java/networking/udp/broadcast/BroadcastingClient.java b/core-java/src/main/java/com/baeldung/java/networking/udp/broadcast/BroadcastingClient.java new file mode 100644 index 0000000000..3162ff0b1e --- /dev/null +++ b/core-java/src/main/java/com/baeldung/java/networking/udp/broadcast/BroadcastingClient.java @@ -0,0 +1,85 @@ +package com.baeldung.java.networking.udp.broadcast; + +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.net.SocketException; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.List; +import java.util.stream.Collectors; + +public class BroadcastingClient { + private DatagramSocket socket; + private InetAddress address; + private int expectedServerCount; + private byte[] buf; + + public BroadcastingClient(int expectedServerCount) throws Exception { + this.expectedServerCount = expectedServerCount; + this.address = InetAddress.getByName("255.255.255.255"); + } + + public int discoverServers(String msg) throws IOException { + initializeSocketForBroadcasting(); + copyMessageOnBuffer(msg); + + // When we want to broadcast not just to local network, call listAllBroadcastAddresses() and execute broadcastPacket for each value. + broadcastPacket(address); + + return receivePackets(); + } + + List listAllBroadcastAddresses() throws SocketException { + List broadcastList = new ArrayList<>(); + Enumeration interfaces = NetworkInterface.getNetworkInterfaces(); + while (interfaces.hasMoreElements()) { + NetworkInterface networkInterface = interfaces.nextElement(); + + if (networkInterface.isLoopback() || !networkInterface.isUp()) { + continue; + } + + broadcastList.addAll(networkInterface.getInterfaceAddresses() + .stream() + .filter(address -> address.getBroadcast() != null) + .map(address -> address.getBroadcast()) + .collect(Collectors.toList())); + } + return broadcastList; + } + + private void initializeSocketForBroadcasting() throws SocketException { + socket = new DatagramSocket(); + socket.setBroadcast(true); + } + + private void copyMessageOnBuffer(String msg) { + buf = msg.getBytes(); + } + + private void broadcastPacket(InetAddress address) throws IOException { + DatagramPacket packet = new DatagramPacket(buf, buf.length, address, 4445); + socket.send(packet); + } + + private int receivePackets() throws IOException { + int serversDiscovered = 0; + while (serversDiscovered != expectedServerCount) { + receivePacket(); + serversDiscovered++; + } + return serversDiscovered; + } + + private void receivePacket() throws IOException { + DatagramPacket packet = new DatagramPacket(buf, buf.length); + socket.receive(packet); + } + + public void close() { + socket.close(); + } +} diff --git a/core-java/src/main/java/com/baeldung/java/networking/udp/broadcast/BroadcastingEchoServer.java b/core-java/src/main/java/com/baeldung/java/networking/udp/broadcast/BroadcastingEchoServer.java new file mode 100644 index 0000000000..afc50e1f40 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/java/networking/udp/broadcast/BroadcastingEchoServer.java @@ -0,0 +1,44 @@ +package com.baeldung.java.networking.udp.broadcast; + +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.net.InetSocketAddress; + +public class BroadcastingEchoServer extends Thread { + + protected DatagramSocket socket = null; + protected boolean running; + protected byte[] buf = new byte[256]; + + public BroadcastingEchoServer() throws IOException { + socket = new DatagramSocket(null); + socket.setReuseAddress(true); + socket.bind(new InetSocketAddress(4445)); + } + + public void run() { + running = true; + + while (running) { + try { + DatagramPacket packet = new DatagramPacket(buf, buf.length); + socket.receive(packet); + InetAddress address = packet.getAddress(); + int port = packet.getPort(); + packet = new DatagramPacket(buf, buf.length, address, port); + String received = new String(packet.getData(), 0, packet.getLength()); + if (received.equals("end")) { + running = false; + continue; + } + socket.send(packet); + } catch (IOException e) { + e.printStackTrace(); + running = false; + } + } + socket.close(); + } +} diff --git a/core-java/src/main/java/com/baeldung/java/networking/udp/multicast/MulticastEchoServer.java b/core-java/src/main/java/com/baeldung/java/networking/udp/multicast/MulticastEchoServer.java new file mode 100644 index 0000000000..cae5c27d95 --- /dev/null +++ b/core-java/src/main/java/com/baeldung/java/networking/udp/multicast/MulticastEchoServer.java @@ -0,0 +1,41 @@ +package com.baeldung.java.networking.udp.multicast; + +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.InetAddress; +import java.net.MulticastSocket; + +public class MulticastEchoServer extends Thread { + + protected MulticastSocket socket = null; + protected byte[] buf = new byte[256]; + protected InetAddress group = null; + + public MulticastEchoServer() throws IOException { + socket = new MulticastSocket(4446); + socket.setReuseAddress(true); + group = InetAddress.getByName("230.0.0.0"); + socket.joinGroup(group); + } + + public void run() { + try { + while (true) { + DatagramPacket packet = new DatagramPacket(buf, buf.length); + socket.receive(packet); + InetAddress address = packet.getAddress(); + int port = packet.getPort(); + packet = new DatagramPacket(buf, buf.length, address, port); + String received = new String(packet.getData(), 0, packet.getLength()); + if (received.equals("end")) { + break; + } + socket.send(packet); + } + socket.leaveGroup(group); + socket.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/core-java/src/main/java/com/baeldung/java/networking/udp/multicast/MulticastingClient.java b/core-java/src/main/java/com/baeldung/java/networking/udp/multicast/MulticastingClient.java new file mode 100644 index 0000000000..4e425055fe --- /dev/null +++ b/core-java/src/main/java/com/baeldung/java/networking/udp/multicast/MulticastingClient.java @@ -0,0 +1,53 @@ +package com.baeldung.java.networking.udp.multicast; + +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetAddress; + +public class MulticastingClient { + private DatagramSocket socket; + private InetAddress group; + private int expectedServerCount; + private byte[] buf; + + public MulticastingClient(int expectedServerCount) throws Exception { + this.expectedServerCount = expectedServerCount; + this.socket = new DatagramSocket(); + this.group = InetAddress.getByName("230.0.0.0"); + } + + public int discoverServers(String msg) throws IOException { + copyMessageOnBuffer(msg); + multicastPacket(); + + return receivePackets(); + } + + private void copyMessageOnBuffer(String msg) { + buf = msg.getBytes(); + } + + private void multicastPacket() throws IOException { + DatagramPacket packet = new DatagramPacket(buf, buf.length, group, 4446); + socket.send(packet); + } + + private int receivePackets() throws IOException { + int serversDiscovered = 0; + while (serversDiscovered != expectedServerCount) { + receivePacket(); + serversDiscovered++; + } + return serversDiscovered; + } + + private void receivePacket() throws IOException { + DatagramPacket packet = new DatagramPacket(buf, buf.length); + socket.receive(packet); + } + + public void close() { + socket.close(); + } +} diff --git a/core-java/src/test/java/com/baeldung/java/networking/udp/broadcast/BroadcastIntegrationTest.java b/core-java/src/test/java/com/baeldung/java/networking/udp/broadcast/BroadcastIntegrationTest.java new file mode 100644 index 0000000000..e3ffbcc052 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/java/networking/udp/broadcast/BroadcastIntegrationTest.java @@ -0,0 +1,39 @@ +package com.baeldung.java.networking.udp.broadcast; + +import org.junit.After; +import org.junit.Test; + +import java.io.IOException; + +import static org.junit.Assert.assertEquals; + +public class BroadcastIntegrationTest { + private BroadcastingClient client; + + @Test + public void whenBroadcasting_thenDiscoverExpectedServers() throws Exception { + int expectedServers = 4; + initializeForExpectedServers(expectedServers); + + int serversDiscovered = client.discoverServers("hello server"); + assertEquals(expectedServers, serversDiscovered); + } + + private void initializeForExpectedServers(int expectedServers) throws Exception { + for (int i = 0; i < expectedServers; i++) { + new BroadcastingEchoServer().start(); + } + + client = new BroadcastingClient(expectedServers); + } + + @After + public void tearDown() throws IOException { + stopEchoServer(); + client.close(); + } + + private void stopEchoServer() throws IOException { + client.discoverServers("end"); + } +} diff --git a/core-java/src/test/java/com/baeldung/java/networking/udp/multicast/MulticastIntegrationTest.java b/core-java/src/test/java/com/baeldung/java/networking/udp/multicast/MulticastIntegrationTest.java new file mode 100644 index 0000000000..26c0704b01 --- /dev/null +++ b/core-java/src/test/java/com/baeldung/java/networking/udp/multicast/MulticastIntegrationTest.java @@ -0,0 +1,39 @@ +package com.baeldung.java.networking.udp.multicast; + +import org.junit.After; +import org.junit.Test; + +import java.io.IOException; + +import static org.junit.Assert.assertEquals; + +public class MulticastIntegrationTest { + private MulticastingClient client; + + @Test + public void whenBroadcasting_thenDiscoverExpectedServers() throws Exception { + int expectedServers = 4; + initializeForExpectedServers(expectedServers); + + int serversDiscovered = client.discoverServers("hello server"); + assertEquals(expectedServers, serversDiscovered); + } + + private void initializeForExpectedServers(int expectedServers) throws Exception { + for (int i = 0; i < expectedServers; i++) { + new MulticastEchoServer().start(); + } + + client = new MulticastingClient(expectedServers); + } + + @After + public void tearDown() throws IOException { + stopEchoServer(); + client.close(); + } + + private void stopEchoServer() throws IOException { + client.discoverServers("end"); + } +}