Java MulticastSocket group chat application

In this article, we discuss a group chat application using the MulticastSocket (Java Platform SE 7) class. MulticastSocket is a (UDP) datagram socket with the additional function of joining other multicast host "groups" on the Internet.

import java.net.*;
import java.io.*;
import java.util.*;

public class GroupChat {
	private static final String TERMINATE = "Exit";
	static String name;
	static volatile boolean finished = false;

	public static void main(String[] args) {
		if (args.length != 2)
			System.out.println("Two arguments required: <multicast-host> <port-number>");
		else {
			try {
				InetAddress group = InetAddress.getByName(args[0]);
				int port = Integer.parseInt(args[1]);
				Scanner sc = new Scanner(System.in);
				System.out.print("Enter your name: ");
				name = sc.nextLine();
				MulticastSocket socket = new MulticastSocket(port);

				// Since we are deploying
				socket.setTimeToLive(0);
				// this on localhost only (For a subnet set it as 1)

				socket.joinGroup(group);
				Thread t = new Thread(new ReadThread(socket, group, port));

				// Spawn a thread for reading messages
				t.start();

				// sent to the current group
				System.out.println("Start typing messages...\n");
				while (true) {
					String message;
					message = sc.nextLine();
					if (message.equalsIgnoreCase(GroupChat.TERMINATE)) {
						finished = true;
						socket.leaveGroup(group);
						socket.close();
						break;
					}
					message = name + ": " + message;
					byte[] buffer = message.getBytes();
					DatagramPacket datagram = new DatagramPacket(buffer, buffer.length, group, port);
					socket.send(datagram);
				}
			} catch (SocketException se) {
				System.out.println("Error creating socket");
				se.printStackTrace();
			} catch (IOException ie) {
				System.out.println("Error reading/writing from/to socket");
				ie.printStackTrace();
			}
		}
	}
}

class ReadThread implements Runnable {
	private MulticastSocket socket;
	private InetAddress group;
	private int port;
	private static final int MAX_LEN = 1000;

	ReadThread(MulticastSocket socket, InetAddress group, int port) {
		this.socket = socket;
		this.group = group;
		this.port = port;
	}

	@Override
	public void run() {
		while (!GroupChat.finished) {
			byte[] buffer = new byte[ReadThread.MAX_LEN];
			DatagramPacket datagram = new DatagramPacket(buffer, buffer.length, group, port);
			String message;
			try {
				socket.receive(datagram);
				message = new String(buffer, 0, datagram.getLength(), "UTF-8");
				if (!message.startsWith(GroupChat.name))
					System.out.println(message);
			} catch (IOException e) {
				System.out.println("Socket closed!");
			}
		}
	}
}

Save the file as GroupChat.java, compile it with javac, and then run the program with the two command-line parameters specified. The multicast host is specified by a class D IP address and a standard UDP port number. Class D IP addresses range from 224.0.0.0 to 239.255.255.255 (inclusive). Address 224.0.0.0 is reserved and should not be used.
The following is an example output of the above procedure:


We use a multicast host with an IP address of 239.0.0.0 and a port number of 1234 (because port numbers 0 to 1023 are reserved). The group has three members: Ironman, CaptainAmerica and Groot. Start all three terminals before sending messages, otherwise messages sent before starting terminals will be lost (because there is no merge buffer to store messages) We need two threads in this application. One is used to accept user input (using the java.util.Scanner class), and the other is used to read messages sent from other clients. Therefore, I separate the threads that perform the read work into ReadThreadclass. To leave the group, any user can type exit to terminate the session.

The above program is executed on a single machine. Socket programming is suitable for distributed programming. The same code fragment can meet this requirement when it appears on different machines with Java installed. This is just the most basic service logic. If the front end is developed, the project will be more attractive. You can use Java's AWT (Abstract window toolkit) or its advanced counterpart Java Swing to develop the front end. Since this is not part of socket programming, I will leave it unchanged without going into the details.
Additional points:

 
 
  • You can incorporate network security features by performing encryption before sending messages over the network.
  • Original technologies such as Caesar password or advanced methods such as RSA can be used to perform encryption and decryption. You can try using Java's RMI (remote method call) to perform the same task.
  • Here, you can make the most of the abstraction provided by Java. However, if your main goal is efficiency, Socket programming is the best choice. Because it does not require any runtime support, it is faster than RMI.

Keywords: Java udp

Added by Doyley on Wed, 08 Sep 2021 07:54:21 +0300