Android Instant Messaging App: Socket Basics
Socket communication is a fundamentla concept in network programming. A socket, also known as a "socket", describes an IP address and port and serves as a handle for a communication chain. Applications typically use sockets to send requests or respond to network requests.
Socket and ServerSocket classes are located in the java.net package. ServerSocket is used on the server side, while Socket is used when establishing a network connection. Upon successful connection, both ends of the application generate a Socket instance, which is used to complete the required session.
Server:
Use ServerSocket to listen on a specified port and wait for client connection requests. When a client connects, a session is created. After the session cmopletes, the connection is closed.
Client:
Use Socket to send a connection request to a specific port on a specific server on the network. Once connected, a session is opened. After the session completes, the Socket is closed.
Ports 0–1023 are reserved for system services. For example, HTTP uses port 80, telnet uses 21, FTP uses 23. When choosing a port number, it is advisable to select a number greater than 1023 to avoid conflicts.
Simple Client/Server Example
Client:
import java.net.*;
import java.io.*;
public class ChatClient {
public static void main(String[] args) throws Exception {
try (Socket socket = new Socket(InetAddress.getLocalHost(), 5469);
BufferedReader serverReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter serverWriter = new PrintWriter(socket.getOutputStream(), true);
BufferedReader consoleReader = new BufferedReader(new InputStreamReader(System.in))) {
String userInput;
while ((userInput = consoleReader.readLine()) != null) {
serverWriter.println(userInput);
String response = serverReader.readLine();
System.out.println("Server response: " + response);
if ("end".equals(userInput)) {
break;
}
}
}
}
}
Server (single-client version):
import java.net.*;
import java.io.*;
public class SingleClientServer {
public static void main(String[] args) throws Exception {
try (ServerSocket serverSocket = new ServerSocket(5469)) {
System.out.println("Server listening on port 5469...");
Socket clientSocket = serverSocket.accept();
System.out.println("Client connected.");
try (BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader consoleReader = new BufferedReader(new InputStreamReader(System.in))) {
String clientMessage;
while ((clientMessage = in.readLine()) != null) {
System.out.println("Client says: " + clientMessage);
System.out.print("Enter response: ");
String serverResponse = consoleReader.readLine();
out.println(serverResponse);
if ("end".equals(serverResponse)) {
break;
}
}
}
}
}
}
Session Example Diagram:
Handling Multiple Clients
To handle multiple clients concurrently, the server must be multithreaded. Each client connection is handled by a separate thread.
import java.net.*;
import java.io.*;
public class MultiClientServer {
public static void main(String[] args) throws Exception {
try (ServerSocket serverSocket = new ServerSocket(5469)) {
System.out.println("Server listening on port 5469...");
while (true) {
Socket clientSocket = serverSocket.accept();
System.out.println("New client connected.");
new ClientHandler(clientSocket).start();
}
}
}
}
class ClientHandler extends Thread {
private Socket clientSocket;
public ClientHandler(Socket socket) {
this.clientSocket = socket;
}
public void run() {
try (BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
BufferedReader consoleReader = new BufferedReader(new InputStreamReader(System.in))) {
String clientMessage;
while ((clientMessage = in.readLine()) != null) {
System.out.println("Client says: " + clientMessage);
System.out.print("Enter response: ");
String serverResponse = consoleReader.readLine();
out.println(serverResponse);
if ("end".equals(serverResponse)) {
break;
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}