A Group Chat Application in Java
Last Updated :
27 Mar, 2025
In this post, a group chat application using MulticastSocket (Java Platform SE 7) class is discussed. A MulticastSocket is a (UDP) DatagramSocket, with additional capabilities for joining "groups" of other multicast hosts on the internet.
Implementation
Java
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
{
// CHANGES HAVE BEEN DONE HERE: Added validation for multicast address and port
try
{
InetAddress group = InetAddress.getByName(args[0]);
if (!group.isMulticastAddress()) {
System.out.println("Error: Invalid multicast address");
return;
}
int port = Integer.parseInt(args[1]);
if (port < 1024 || port > 65535) {
System.out.println("Error: Port number must be between 1024 and 65535");
return;
}
Scanner sc = new Scanner(System.in);
System.out.print("Enter your name: ");
name = sc.nextLine();
MulticastSocket socket = new MulticastSocket(port);
// CHANGES HAVE BEEN DONE HERE: Set proper TTL value
socket.setTimeToLive(1); // Changed from 0 to 1 for local subnet
socket.joinGroup(group);
Thread t = new Thread(new ReadThread(socket,group,port));
t.start();
System.out.println("Start typing messages...\n");
try {
while(true)
{
String message = sc.nextLine();
if(message.equalsIgnoreCase(GroupChat.TERMINATE))
{
finished = true;
// CHANGES HAVE BEEN DONE HERE: Proper cleanup
socket.leaveGroup(group);
socket.close();
sc.close(); // Added scanner close
break;
}
message = name + ": " + message;
byte[] buffer = message.getBytes();
DatagramPacket datagram = new DatagramPacket(buffer,buffer.length,group,port);
socket.send(datagram);
}
} finally {
if (!socket.isClosed()) {
socket.leaveGroup(group);
socket.close();
}
sc.close();
}
}
catch(UnknownHostException uhe) {
System.out.println("Error: Invalid multicast host");
uhe.printStackTrace();
}
catch(NumberFormatException nfe) {
System.out.println("Error: Port must be a number");
nfe.printStackTrace();
}
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 final MulticastSocket socket; // CHANGES HAVE BEEN DONE HERE: Made final
private final InetAddress group;
private final 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);
try
{
socket.receive(datagram);
String message = new String(buffer, 0, datagram.getLength(), "UTF-8");
if(!message.startsWith(GroupChat.name))
System.out.println(message);
}
catch(SocketException se) {
if (!GroupChat.finished) {
System.out.println("Socket error: " + se.getMessage());
}
}
catch(IOException e)
{
if (!GroupChat.finished) {
System.out.println("Error reading message: " + e.getMessage());
}
}
}
}
}
Save the file as GroupChat.java and compile it using javac and then run the program using two command line arguments as specified. A multicast host is specified by a class D IP address and by a standard UDP port number. Class D IP addresses are in the range 224.0.0.0 to 239.255.255.255, inclusive. The address 224.0.0.0 is reserved and should not be used. Here is a sample output of the above program:



We have used the multicast host IP address as 239.0.0.0 and the port number as 1234 (since the port numbers 0 through 1023 are reserved). There are 3 members in the group: Ironman, CaptainAmerica, and Groot. Start all three terminals first before sending the message, otherwise messages which are sent before starting the terminal are lost (since there is no facility of buffer incorporated to store the messages.) We need two threads in this application. One for accepting the user input (using the java.util.Scanner class) and the other for reading the messages sent from other clients. Hence I have separated the thread which does the reading work into ReadThreadclass. For leaving the group, any of the user can type in Exit to terminate the session. The above program is executed on a single machine. Socket programming is meant for distributed programming. The same piece of code snippet when present on different machines which have Java installed can satisfy that requirement. This is just the bare bones service logic. The project would be even more fascinating if the front-end is developed. You can use Java’s AWT (Abstract Window Toolkit) or its advanced counterpart, Java Swing to develop the front end. Since this wouldn’t be part of Socket programming I’m leaving it untouched without getting into the details.
Additional points:
- You can incorporate network security feature by performing encryption before sending the message over the network.
- Primitive techniques such as Caesar cipher or advanced methods such as RSA can be used to perform encryption-decryption. You can try using Java’s RMI (Remote Method Invocation) to perform the same task.
- Here, you can leverage the abstraction offered by Java to maximum extent. However, if your primary objective is efficiency, then Socket programming is the best choice. Since it doesn’t require any run time support, it is a bit faster compared to RMI.