Share
Explore

Lab Workbook: Building the Chat Server with Java J2EE

Introduction

In Java, services are enabled by PORTS.

A Service is a METHOD CALL.
Calling a Method on a REMOTE JVM? You will be connect to the PORT in that REMOTE JVM for that METHOD.
HAND IN: A word Document with all code and screen shots demonstrating the successfuly operation of this illustration of how Java Sockets work, uploaded to the Moodle Assigment Page.
Due December 15.

info

Preamble: From Sockets to SOAP-Based Web Services

In this lab, you will build a fundamental networking application—a simple chat program using Java sockets.
This exercise introduces core concepts of object communication where the objects live in different JVMs connected by TCP/IP network.
Understanding how data flows between a client and server in this low-level setting is essential as we progress towards more advanced technologies like **Remote Method Invocation (RMI)** and **SOAP-based web services**.
Socket programming allows us to establish direct, low-level connections between systems, enabling real-time data exchange.
While this is effective for small, simple applications, real-world systems often require more sophisticated, robust, and scalable solutions.
As we move up the abstraction ladder, RMI will introduce the concept of calling methods on remote objects as if they were local, simplifying the complexity of network communication. Building on this, SOAP (Simple Object Access Protocol) offers a standardized, XML-based framework for exchanging structured data over a network, suitable for large-scale, distributed applications.
By learning socket communication first, you'll gain a deeper appreciation of how high-level web services—such as SOAP—are built on the same fundamental principles of client-server interaction.

SOAP services, unlike socket-based programs, add essential features such as platform independence, language-agnostic communication, and standardized messaging, all of which are vital for modern enterprise-level distributed applications.
This lab sets the foundation for that journey, connecting the dots from basic networking to sophisticated J2EE web services architecture.

Lesson 1: Introduction to Java Networking with Sockets

Welcome to your journey towards understanding J2EE web services!
In this initial step, we will lay the foundation by exploring a simple concept: a **socket-based chat application**.

This will help you grasp the basics of how text messages can be sent between computers over a TCP/IP connection, setting the stage for more advanced topics like Remote Method Invocation (RMI) in future lessons.
---
### **Objective** ​By the end of this lesson, you will: 1. Understand the concept of sockets and how they enable communication between two systems. 2. Implement a simple Java socket-based chat application. 3. Gain an appreciation of how TCP/IP networking underpins higher-level services like web services in J2EE.
---
### **Prerequisites** - Basic understanding of Java SE. - Familiarity with input/output streams, basic Java programming, and threads.
---
### **Tools Required** - **Java Development Kit (JDK)** (preferably version 11 or above). - Any Java Integrated Development Environment (IDE) such as Eclipse, IntelliJ IDEA, or NetBeans.

Concept Overview**

What are Sockets?

In networking, a **socket** is one endpoint of a two-way communication link between two programs running on a network.

It is bound to a port number so that the Transmission Control Protocol (TCP) layer can identify the application that data is destined for.
In simpler terms, sockets allow two computers (or programs) to "talk" to each other over the internet or a local network.

How Sockets Work A socket connection is established as follows:

1. **Server**: Waits for a client to connect.
2. **Client**: Initiates a connection to the server.
3. **Connection Established**: The server and client can now send and receive data.
4. **Data Transfer**: The client and server exchange messages (data).
5. **Close**: The connection is terminated when either side decides to close the socket.
This socket-to-socket communication forms the basis of many modern-day Internet applications, such as chat apps, file transfer systems, and even web services.
---

Step-by-Step Instructions

Step 1: Create the Server

First, we will create the server-side of the chat application. The server will wait for a connection from the client and, once connected, will facilitate the exchange of messages.
import java.io.*; import java.net.*;
public class ChatServer { private ServerSocket serverSocket; private Socket clientSocket; private PrintWriter out; private BufferedReader in;
public void start(int port) { try { serverSocket = new ServerSocket(port); System.out.println("Server started. Waiting for a client..."); clientSocket = serverSocket.accept(); // Wait for a client to connect System.out.println("Client connected."); // Streams for sending and receiving messages out = new PrintWriter(clientSocket.getOutputStream(), true); in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); String inputLine; while ((inputLine = in.readLine()) != null) { System.out.println("Client: " + inputLine); if ("exit".equalsIgnoreCase(inputLine)) { out.println("Goodbye!"); break; } out.println("Server: " + inputLine); } } catch (IOException e) { e.printStackTrace(); } finally { stop(); } }
public void stop() { try { in.close(); out.close(); clientSocket.close(); serverSocket.close(); } catch (IOException e) { e.printStackTrace(); } }
public static void main(String[] args) { ChatServer server = new ChatServer(); server.start(6666); // Use port 6666 for communication } } ​
image.png
#### **Step 2: Create the Client** Now, let's create the client-side of the application. The client will initiate the connection and then send and receive messages from the server.
```java import java.io.*; import java.net.*;
public class ChatClient { private Socket socket; private PrintWriter out; private BufferedReader in;
public void start(String ip, int port) { try { socket = new Socket(ip, port); // Connect to the server System.out.println("Connected to the server.");
out = new PrintWriter(socket.getOutputStream(), true); in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in)); String userInput; System.out.println("Type your message (type 'exit' to quit):"); while ((userInput = stdIn.readLine()) != null) { out.println(userInput); // Send user input to server System.out.println(in.readLine()); // Receive and print server's response if ("exit".equalsIgnoreCase(userInput)) { break; } }
} catch (IOException e) { e.printStackTrace(); } finally { stop(); } }
public void stop() { try { in.close(); out.close(); socket.close(); } catch (IOException e) { e.printStackTrace(); } }
public static void main(String[] args) { ChatClient client = new ChatClient(); client.start("127.0.0.1", 6666); // Connect to localhost on port 6666 } } ```
---
### **Step 3: Run the Application** 1. **Run the Server**: - Compile and run the `ChatServer` class. - The server will start and wait for a client to connect. 2. **Run the Client**: - In a separate terminal or IDE instance, compile and run the `ChatClient` class. - The client will connect to the server and begin sending messages. 3. **Exchange Messages**: - The client and server can now exchange messages. Type a message in the client and see it appear in the server's console, and vice versa.
---
### **Key Concepts** - **Sockets**: Provide communication between two machines using TCP/IP. - **Input/Output Streams**: Enable reading from and writing to sockets. - **Threading**: In a more complex version, we could use threads to handle multiple clients simultaneously, but for now, we'll stick to a single client-server setup.
---
### **Exercise: Extend the Application** To solidify your understanding, try the following: - **Multiple Clients**: Modify the server to handle multiple clients simultaneously using threads. - **Enhanced Messaging**: Add features like message formatting or user nicknames. - **Error Handling**: Improve the robustness of your application by handling various exceptions.
---
### **Conclusion** By implementing this simple socket-based chat application, you now have a solid foundation in Java networking. In the next lesson, we will build on this concept to explore Remote Method Invocation (RMI) and eventually move towards J2EE web services.
This step-by-step approach ensures that by the time we reach the complexities of J2EE, you will have a clear understanding of how lower-level networking concepts like sockets play a role in high-level web services.


info

Multi-client Chat

Lab Update: Adding Multi-Client Support with User Identification

We will now extend the previous socket-based chat application to allow multiple clients to connect simultaneously.
Each client will enter a username upon connection, which will be used to identify them in the chat.
The server will manage multiple client connections by utilizing threads, allowing for concurrent communication between several clients.

Updated Objective

By the end of this lesson, you will:
Implement multi-client support in a socket-based Java chat application using threads.
Allow clients to enter a username, which will be used to identify them in the chat.
Broadcast messages from one client to all connected clients, simulating a group chat.

Step 1: Modify the Server for Multi-Client Support

To handle multiple clients, the server needs to spawn a new thread for each incoming client connection.
This way, multiple clients can interact with the server simultaneously.
import java.io.*;
import java.net.*;
import java.util.*;

public class ChatServer {
private ServerSocket serverSocket;
private Set<ClientHandler> clientHandlers = new HashSet<>();

public void start(int port) {
try {
serverSocket = new ServerSocket(port);
System.out.println("Server started. Waiting for clients...");

while (true) {
Socket clientSocket = serverSocket.accept();
ClientHandler clientHandler = new ClientHandler(clientSocket, this);
clientHandlers.add(clientHandler);
new Thread(clientHandler).start(); // Start a new thread for each client
System.out.println("New client connected.");
}
} catch (IOException e) {
e.printStackTrace();
}
}

public synchronized void broadcastMessage(String message, ClientHandler sender) {
for (ClientHandler clientHandler : clientHandlers) {
if (clientHandler != sender) { // Send to all except the sender
clientHandler.sendMessage(message);
}
}
}

public synchronized void removeClient(ClientHandler clientHandler) {
clientHandlers.remove(clientHandler);
}

public static void main(String[] args) {
ChatServer server = new ChatServer();
server.start(6666); // Use port 6666 for communication
}
}

class ClientHandler implements Runnable {
private Socket socket;
private PrintWriter out;
private BufferedReader in;
private String username;
private ChatServer server;

public ClientHandler(Socket socket, ChatServer server) {
this.socket = socket;
this.server = server;
}

@Override
public void run() {
try {
// Setup I/O streams
out = new PrintWriter(socket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

Want to print your doc?
This is not the way.
Try clicking the ⋯ next to your doc name or using a keyboard shortcut (
CtrlP
) instead.