How to make our sender-server-receiver Java code into a client-server mail exchange code that does the follwoing:
Each client can send and receive simultaneously (i.e. multi-threading): using multithreading, each client should act as a receiver waiting for incoming emails while being able to send new emails at the same time. In other words, both functionalities should work at the same time.
Please I need help on how to make the multi-threaded server so multiple clients can send emails at once.
What I have tried:
Server code
<pre>import java.io.*;
import java.net.*;
import java.util.*;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
public class Server{
private static final Set<String> validEmails = new HashSet<>();
private static final Map<String, InetAddress> emailToAddressMap = new HashMap<>();
private static final Map<String, Integer> emailToPortMap = new HashMap<>();
private static final int BUFFER_SIZE = 1024;
public static void main(String[] args) {
DatagramSocket serverSocket = null;
preSavedEmails();
loadEmailToHostNameMap();
try {
serverSocket = new DatagramSocket(12346);
String serverHostName = InetAddress.getLocalHost().getHostName();
System.out.println("Mail server starting at host: " + serverHostName );
System.out.println("Waiting to be contacted for transferring Mail.. ");
System.out.println();
StringBuilder messageBuilder = new StringBuilder();
while (true) {
byte[] receiveData = new byte[BUFFER_SIZE];
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
serverSocket.receive(receivePacket);
ClientHandler clientHandler = new ClientHandler(serverSocket, receivePacket);
Thread clientThread = new Thread(clientHandler);
clientThread.start();
serverSocket.receive(receivePacket);
String message = new String(receivePacket.getData(), 0, receivePacket.getLength());
String segment = new String(receivePacket.getData(), 0, receivePacket.getLength()).trim();
String[] parts = message.split("_");
String timestamp = java.time.LocalDateTime.now().toString();
InetAddress clientAddress = receivePacket.getAddress();
int clientPort = receivePacket.getPort();
if (message.equals("Connect")) {
System.out.println("Connection request received from " + clientAddress + ": " + clientPort);
send(serverSocket, clientAddress, "ACK", clientPort);
System.out.println("Sent ACK to client " + clientAddress + ": " + clientPort);
continue;
} else if (message.equals("ACK ACK")) {
System.out.println("Connection established with " + clientAddress + ": " + clientPort);
System.out.println();
continue;
}
else if (message.equals("TERMINATE_CONNECTION")) {
System.out.println();
System.out.println("Termination request received from " + clientAddress + ": " + clientPort);
send(serverSocket, clientAddress, "ACK", clientPort);
System.out.println("Sent ACK to client " + clientAddress + ": " + clientPort + " for termination request.");
DatagramPacket finalAckAckPacket = new DatagramPacket(new byte[1024], 1024);
serverSocket.receive(finalAckAckPacket);
String finalAckAck = new String(finalAckAckPacket.getData(), 0, finalAckAckPacket.getLength());
if (finalAckAck.equals("ACK ACK")) {
System.out.println("Final ACK ACK received from " + clientAddress + ": " + clientPort + ". Connection terminated.");
} else {
System.out.println("Unexpected message received after termination request: " + finalAckAck);
}
continue;
} else {
if (segment.contains("END_EMAIL")) {
messageBuilder.append(segment.replace("END_EMAIL", ""));
processAndForwardEmail(serverSocket, messageBuilder.toString(), clientAddress, clientPort);
messageBuilder.setLength(0);
} else {
messageBuilder.append(segment);
}
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (serverSocket != null && !serverSocket.isClosed()) {
serverSocket.close();
}
}
}
private static void send(DatagramSocket socket, InetAddress address, String message, int port) throws IOException {
byte[] data = message.getBytes();
DatagramPacket packet = new DatagramPacket(data, data.length, address, port);
socket.send(packet);
}
private static String receive(DatagramSocket socket) throws IOException {
byte[] data = new byte[1024];
DatagramPacket packet = new DatagramPacket(data, data.length);
socket.receive(packet);
return new String(packet.getData(), 0, packet.getLength());
}
private static void preSavedEmails() {
validEmails.add(" client1@example.com");
validEmails.add(" client2@example.com");
validEmails.add(" client3@example.com");
validEmails.add(" client4@example.com");
validEmails.add(" client5@example.com");
}
private static boolean verifyEmail(String email) {
return validEmails.contains(email);
}
private static void loadEmailToHostNameMap() {
try {
emailToAddressMap.put("client1@example.com", InetAddress.getByName("localhost"));
emailToPortMap.put("client1@example.com", 12347);
emailToAddressMap.put("client2@example.com", InetAddress.getByName("localhost"));
emailToPortMap.put("client2@example.com", 12347);
emailToAddressMap.put("client3@example.com", InetAddress.getByName("localhost"));
emailToPortMap.put("client3@example.com", 12347);
emailToAddressMap.put("client4@example.com", InetAddress.getByName("localhost"));
emailToPortMap.put("client4@example.com", 12347);
emailToAddressMap.put("client5@example.com", InetAddress.getByName("localhost"));
emailToPortMap.put("client5@example.com", 12347);
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
private static void forwardEmailToReceiver(DatagramSocket serverSocket, String mailTo, String message) throws IOException {
if (emailToAddressMap.containsKey(mailTo) && emailToPortMap.containsKey(mailTo)) {
InetAddress receiverAddress = emailToAddressMap.get(mailTo);
int receiverPort = emailToPortMap.get(mailTo);
String fullMessage = message + "END";
byte[] forwardData = fullMessage.getBytes();
DatagramPacket forwardPacket = new DatagramPacket(forwardData, forwardData.length, receiverAddress, receiverPort);
serverSocket.send(forwardPacket);
System.out.println("Email forwarded to " + mailTo);
System.out.println();
} else {
System.out.println("Email to " + mailTo + " could not be forwarded. Receiver not found.");
System.out.println();
}
}
private static void processAndForwardEmail(DatagramSocket serverSocket, String fullMessage, InetAddress clientAddress, int clientPort) throws IOException {
System.out.println("Processing email received from " + clientAddress);
Map<String, String> emailDetails = parseEmailContent(fullMessage);
String formattedEmail = fullMessage.replace('_', '\n');
System.out.println("Email Content: \n" + formattedEmail);
System.out.println();
saveEmail(emailDetails);
if (emailDetails.containsKey("ATTACHMENT")) {
String sender = emailDetails.get("FROM");
String receiver = emailDetails.get("TO");
String attachmentInfo = emailDetails.get("ATTACHMENT");
saveAttachment(sender, receiver, attachmentInfo);
}
String recipientEmail = emailDetails.get("TO");
if (recipientEmail != null) {
forwardEmailToReceiver(serverSocket, recipientEmail, fullMessage);
} else {
System.out.println("No valid recipient found in the email details.");
}
}
private static Map<String, String> parseEmailContent(String emailContent) {
Map<String, String> details = new HashMap<>();
String[] parts = emailContent.split("_");
for (String part : parts) {
int colonIndex = part.indexOf(':');
if (colonIndex > -1) {
String key = part.substring(0, colonIndex);
String value = part.substring(colonIndex + 1);
details.put(key, value);
}
}
return details;
}
private static void saveEmail(Map<String, String> emailDetails) throws IOException {
String senderDirectory = "./ServerEmails/" + emailDetails.get("FROM") + "/sent";
String receiverDirectory = "./ServerEmails/" + emailDetails.get("TO") + "/inbox";
new File(senderDirectory).mkdirs();
new File(receiverDirectory).mkdirs();
String timestamp = String.valueOf(System.currentTimeMillis());
String subjectFormatted = emailDetails.get("SUBJECT").replace(" ", "_");
String emailFileName = subjectFormatted + "_" + timestamp + ".txt";
File senderFile = new File(senderDirectory, emailFileName);
File receiverFile = new File(receiverDirectory, emailFileName);
saveEmailToFile(emailDetails, senderFile);
saveEmailToFile(emailDetails, receiverFile);
}
private static void saveEmailToFile(Map<String, String> emailDetails, File file) throws IOException {
try (PrintWriter out = new PrintWriter(new FileWriter(file))) {
out.println("From: " + emailDetails.get("FROM"));
out.println("To: " + emailDetails.get("TO"));
out.println("Subject: " + emailDetails.get("SUBJECT"));
out.println("Body:\n" + emailDetails.get("BODY"));
}
System.out.println("Email saved to: " + file.getAbsolutePath());
}
private static void saveAttachment(String sender, String receiver, String attachmentInfo) throws IOException {
int firstColon = attachmentInfo.indexOf(':');
String fileName = attachmentInfo.substring(0, firstColon);
String base64Data = attachmentInfo.substring(firstColon + 1);
byte[] data = Base64.getDecoder().decode(base64Data);
String senderAttachmentDir = "./ServerEmails/" + sender + "/sent/attachments";
String receiverAttachmentDir = "./ServerEmails/" + receiver + "/inbox/attachments";
new File(senderAttachmentDir).mkdirs();
new File(receiverAttachmentDir).mkdirs();
File senderAttachmentFile = new File(senderAttachmentDir, fileName);
File receiverAttachmentFile = new File(receiverAttachmentDir, fileName);
saveAttachmentToFile(data, senderAttachmentFile);
saveAttachmentToFile(data, receiverAttachmentFile);
}
private static void saveAttachmentToFile(byte[] data, File file) throws IOException {
try (FileOutputStream out = new FileOutputStream(file)) {
out.write(data);
}
System.out.println("Attachment saved to: " + file.getAbsolutePath());
}
}
class ClientHandler implements Runnable {
DatagramSocket serverSocket;
private DatagramPacket receivePacket;
private DatagramPacket sendPacket;
private InetAddress clientAddress = null;
private int clientPort = 0;
private byte[] receiveData;
private byte[] sendData;
private int serverPort;
String IP_address, Transfer_Type, File_Name, Msg;
byte[] Body_Data;
int Sequence_Num = 0;
int ACK_Num = 0;
long bLength;
String[] header;
private static final int BUFFER_SIZE = 1024;
public ClientHandler(DatagramSocket serverSocket, DatagramPacket receivePacket) {
this.serverSocket = serverSocket;
this.receivePacket = receivePacket;
this.clientAddress = receivePacket.getAddress();
this.clientPort = receivePacket.getPort();
}
@Override
public void run() {
try {
System.out.println("Client " + Thread.currentThread().getId());
handleClientRequest();
} catch (IOException e) {
e.printStackTrace();
}
}
private void handleClientRequest() throws IOException {
String message = new String(receivePacket.getData(), 0, receivePacket.getLength());
if ("Connect".equals(message)) {
System.out.println("Connection request received from " + clientAddress + ":" + clientPort);
send("ACK");
System.out.println("Sent ACK to client " + clientAddress + ":" + clientPort);
} else if ("TERMINATE_CONNECTION".equals(message)) {
System.out.println("Termination request received from " + clientAddress + ":" + clientPort);
send("ACK");
System.out.println("Sent ACK to client " + clientAddress + ":" + clientPort + " for termination request.");
} else {
System.out.println("Received unknown request from client " + clientAddress + ":" + clientPort + ": " + message);
}
}
private void send(String message) throws IOException {
byte[] sendData = message.getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, clientAddress, clientPort);
serverSocket.send(sendPacket);
}
}
Sender/client code
<pre>import java.io.*;
import java.net.*;
import java.util.*;
import java.nio.file.Files;
import java.nio.file.Paths;
public class Sender {
public static void main(String[] args) {
DatagramSocket clientSocket = null;
int sequenceNumber = 1;
try{
clientSocket = new DatagramSocket();
InetAddress serverAddress = InetAddress.getByName("localhost");
Scanner scanner = new Scanner(System.in);
System.out.println("Mail client starting on host: " + InetAddress.getLocalHost().getHostName());
System.out.println();
serverAddress = null;
while (serverAddress == null) {
System.out.print("Type name of Mail server: ");
String serverName = scanner.nextLine();
try {
serverAddress = InetAddress.getByName(serverName);
} catch (UnknownHostException e) {
System.out.println("Server name is not available. Please enter a valid server name.");
continue;
}
}
System.out.println("Initiating connection to the mail server. Sending Connect...");
byte[] initData = "Connect".getBytes();
DatagramPacket initPacket = new DatagramPacket(initData, initData.length, serverAddress, 12346);
clientSocket.send(initPacket);
byte[] ackData = new byte[1024];
DatagramPacket ackPacket = new DatagramPacket(ackData, ackData.length);
clientSocket.receive(ackPacket);
String ackMsg = new String(ackPacket.getData(), 0, ackPacket.getLength());
if (!"ACK".equals(ackMsg.trim())) {
System.out.println("Failed to connect to the server. Exiting...");
return;
}
else {
System.out.println("Received ACK from the server.");
}
System.out.println("Sending ACK ACK to the server...");
byte[] ackAckData = "ACK ACK".getBytes();
DatagramPacket ackAckPacket = new DatagramPacket(ackAckData, ackAckData.length, serverAddress, 12346);
clientSocket.send(ackAckPacket);
System.out.println("Connected successfully to the server.");
System.out.println();
while (true) {
Scanner option = new Scanner(System.in);
System.out.println("ENTER AN OPTION TO PROCEED:");
System.out.println("[1] Sync inbox");
System.out.println("[2] Create an email");
System.out.println("[3] Terminate Connection");
int option_of_client = option.nextInt();
if (option_of_client == 1) {
Scanner console = new Scanner(System.in);
System.out.println("Enter your email address to proceed: ");
String clientEmail = console.nextLine();
System.out.println("Syncing inbox...");
String syncRequest = "SYNC_INBOX";
byte[] syncRequestData = syncRequest.getBytes();
DatagramPacket syncPacket = new DatagramPacket(syncRequestData, syncRequestData.length,
serverAddress, 12346);
clientSocket.send(syncPacket);
byte[] syncAckData = new byte[1024];
DatagramPacket syncAckPacket = new DatagramPacket(syncAckData, syncAckData.length);
clientSocket.receive(syncAckPacket);
String syncAckMsg = new String(syncAckPacket.getData(), 0, syncAckPacket.getLength());
if ("ACK".equals(syncAckMsg.trim())) {
System.out.println("Inbox sync request acknowledged by the server.");
} else {
System.out.println("Failed to sync inbox. Server response: " + syncAckMsg);
}
}
else if(option_of_client == 2) {
System.out.println("\nCreating New Email...");
String mailTo = getEmailInput(scanner, "To", "@example.com");
String mailFrom = getEmailInput(scanner, "From", "@example.com");
String subject = getNonEmptyInput(scanner, "Subject");
String body = getNonEmptyInput(scanner, "Body");
String emailHeader = "TO_" + mailTo + "_FROM_" + mailFrom + "_SUBJECT_" + subject + "_BODY_" + body + "_SEQ_" + sequenceNumber;
byte[] emailHeaderData = emailHeader.getBytes();
saveEmailToFile(sequenceNumber, emailHeader, null);
DatagramPacket sendPacket = new DatagramPacket(emailHeaderData, emailHeaderData.length, serverAddress, 12346);
clientSocket.send(sendPacket);
System.out.println("Email sent with sequence number " + sequenceNumber);
byte[] attachmentData = null;
System.out.print("Do you want to add an attachment? (yes/no): ");
if ("yes".equalsIgnoreCase(scanner.nextLine())) {
System.out.print("Type the attachment path: ");
String attachmentPath = scanner.nextLine();
File file = new File(attachmentPath);
if (file.exists() && file.isFile()) {
attachmentData = Files.readAllBytes(file.toPath());
attachmentData = Base64.getEncoder().encode(attachmentData);
if (attachmentData != null) {
DatagramPacket sendAttachment = new DatagramPacket(attachmentData, attachmentData.length, serverAddress, 12346);
clientSocket.send(sendAttachment);
System.out.println("Attachment sent.");
}
if (emailHeaderData.length + attachmentData.length > 1024) {
System.out.println("The attachment is too large. Cannot send this email.");
continue;
}
} else {
System.out.println("File does not exist or is not a file.");
}
}
saveEmailToFile(sequenceNumber, emailHeader, attachmentData);
byte[] receiveEmailACK = new byte[1024];
DatagramPacket receiveEmailAckData = new DatagramPacket(receiveEmailACK, receiveEmailACK.length);
clientSocket.receive(receiveEmailAckData);
String serverConfirmation2 = new String(receiveEmailAckData.getData(), 0, receiveEmailAckData.getLength());
if (serverConfirmation2.startsWith("ACK_" + sequenceNumber)) {
System.out.println("ACK received from the server: " + serverConfirmation2);
}
byte[] finalServerConfirmationData = new byte[1024];
DatagramPacket finalServerConfirmationPacket = new DatagramPacket(finalServerConfirmationData, finalServerConfirmationData.length);
clientSocket.receive(finalServerConfirmationPacket);
String finalServerConfirmation = new String(finalServerConfirmationPacket.getData(), 0, finalServerConfirmationPacket.getLength());
if (finalServerConfirmation.contains("250")) {
String timestamp = finalServerConfirmation.substring(11);
System.out.println("Email received successfully at " + timestamp);
}
else if (finalServerConfirmation.contains("501")) {
System.out.println("501 Error - Headers are invalid.");
}
else if (finalServerConfirmation.contains("550")) {
System.out.println("550 Error - Email address doesn't exist.");
}
else {
System.out.println("Unknown response received: " + finalServerConfirmation);
}
if (finalServerConfirmation.contains("250") || finalServerConfirmation.contains("501") || finalServerConfirmation.contains("550")) {
String ackForFinalConfirmation = "ACK_FOR_CONFIRMATION_" + sequenceNumber;
byte[] ackForFinalConfirmationBytes = ackForFinalConfirmation.getBytes();
DatagramPacket ackForFinalConfirmationPacket = new DatagramPacket(ackForFinalConfirmationBytes, ackForFinalConfirmationBytes.length, serverAddress, 12346);
clientSocket.send(ackForFinalConfirmationPacket);
System.out.println("Sent acknowledgment for the final confirmation message to the server.");
}
sequenceNumber++;
System.out.println();
System.out.print("Do you want to send another email? Type anything to continue or 'quit' to quit: ");
System.out.println();
String nextAction = scanner.nextLine();
if ("quit".equalsIgnoreCase(nextAction)) {
System.out.println("Sending TERMINATE_CONNECTION to the server...");
String terminateConnection = "TERMINATE_CONNECTION";
byte[] terminateData = terminateConnection.getBytes();
DatagramPacket terminationPacket = new DatagramPacket(terminateData, terminateData.length, serverAddress, 12346);
clientSocket.send(terminationPacket);
byte[] ackTerminateData = new byte[1024];
DatagramPacket ackTerminatePacket = new DatagramPacket(ackTerminateData, ackTerminateData.length);
clientSocket.receive(ackTerminatePacket);
String ackTerminateMsg = new String(ackTerminatePacket.getData(), 0, ackTerminatePacket.getLength());
if ("ACK".equals(ackTerminateMsg.trim())) {
System.out.println("Received ACK from the server. Sending ACK ACK...");
byte[] ackAckTermData = "ACK ACK".getBytes();
DatagramPacket ackAckTermPacket = new DatagramPacket(ackAckTermData, ackAckTermData.length, serverAddress, 12346);
clientSocket.send(ackAckTermPacket);
System.out.println("Final handshake completed. Disconnecting...");
} else {
System.out.println("Unexpected response from the server: " + ackTerminateMsg);
}
break;
}
System.out.println();
}
else if ((option_of_client == 3)) {
System.out.println("Sending TERMINATE_CONNECTION to the server...");
String terminateConnection = "TERMINATE_CONNECTION";
byte[] terminateData = terminateConnection.getBytes();
DatagramPacket terminationPacket = new DatagramPacket(terminateData, terminateData.length,
serverAddress, 12346);
clientSocket.send(terminationPacket);
byte[] ackTerminateData = new byte[1024];
DatagramPacket ackTerminatePacket = new DatagramPacket(ackTerminateData, ackTerminateData.length);
clientSocket.receive(ackTerminatePacket);
String ackTerminateMsg = new String(ackTerminatePacket.getData(), 0, ackTerminatePacket.getLength());
if ("ACK".equals(ackTerminateMsg.trim())) {
System.out.println("Received ACK from the server. Sending ACK ACK...");
byte[] ackAckTermData = "ACK ACK".getBytes();
DatagramPacket ackAckTermPacket = new DatagramPacket(ackAckTermData, ackAckTermData.length,
serverAddress, 12346);
clientSocket.send(ackAckTermPacket);
System.out.println("Final handshake completed. Disconnecting...");
} else {
System.out.println("Unexpected response from the server: " + ackTerminateMsg);
}
break;
}
}
scanner.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (clientSocket != null && !clientSocket.isClosed()) {
clientSocket.close();
}
}
}
private static String getEmailInput(Scanner scanner, String field, String suffix) {
String input;
do {
System.out.print(field + ": ");
input = scanner.nextLine();
if (!input.endsWith(suffix)) {
System.out.println("Invalid " + field + " address. Must end with " + suffix + ". Please re-enter.");
}
} while (!input.endsWith(suffix));
return input;
}
private static String getNonEmptyInput(Scanner scanner, String field) {
String input;
do {
System.out.print(field + ": ");
input = scanner.nextLine();
if (input.isEmpty()) {
System.out.println(field + " cannot be empty. Please enter a " + field.toLowerCase() + ".");
}
} while (input.isEmpty());
return input;
}
private static void saveEmailToFile(int sequenceNumber, String emailContent, byte[] attachmentData) throws IOException {
String directoryPath = "SentEmails";
File directory = new File(directoryPath);
if (!directory.exists()) {
directory.mkdirs();
}
if (emailContent != null && !emailContent.isEmpty()) {
String emailFilePath = directoryPath + "/Email_" + sequenceNumber + ".txt";
Files.write(Paths.get(emailFilePath), emailContent.getBytes());
System.out.println("Email content saved to " + emailFilePath);
}
if (attachmentData != null) {
String attachmentFilePath = directoryPath + "/Attachment_" + sequenceNumber;
Files.write(Paths.get(attachmentFilePath), attachmentData);
System.out.println("Email attachment saved to " + attachmentFilePath);
}
}
}
Receiver code
<pre>import java.io.*;
import java.net.*;
import java.util.*;
public class Receiver {
public static void main(String[] args) {
DatagramSocket receiverSocket = null;
try {
receiverSocket = new DatagramSocket(12347);
System.out.println("Sending Connect to the server...");
InetAddress serverAddress = InetAddress.getByName("localhost");
byte[] initData = "Connect".getBytes();
DatagramPacket initPacket = new DatagramPacket(initData, initData.length, serverAddress, 12346);
receiverSocket.send(initPacket);
byte[] ackData = new byte[1024];
DatagramPacket ackPacket = new DatagramPacket(ackData, ackData.length);
receiverSocket.receive(ackPacket);
String ackMsg = new String(ackPacket.getData(), 0, ackPacket.getLength());
if (!"ACK".equals(ackMsg.trim())) {
System.out.println("Failed to connect to the server. Exiting...");
return;
}
else {
System.out.println("Received ACK from the server.");
}
System.out.println("Sending ACK ACK to the server...");
byte[] ackAckData = "ACK ACK".getBytes();
DatagramPacket ackAckPacket = new DatagramPacket(ackAckData, ackAckData.length, serverAddress, 12346);
receiverSocket.send(ackAckPacket);
System.out.println("Handshake completed. Listening to incoming emails...");
System.out.println();
File directory = new File("ReceivedEmails");
if (!directory.exists()) {
directory.mkdir();
}
while (true) {
byte[] receiveBuffer = new byte[1024];
DatagramPacket receivePacket = new DatagramPacket(receiveBuffer, receiveBuffer.length);
receiverSocket.receive(receivePacket);
String receivedEmail = new String(receivePacket.getData(), 0, receivePacket.getLength());
System.out.println("Received email: " + receivedEmail);
String ackResponse = "ACK_FROM_RECEIVER";
byte[] ackResponseBytes = ackResponse.getBytes();
DatagramPacket ackPacket2 = new DatagramPacket(ackResponseBytes, ackResponseBytes.length, receivePacket.getAddress(), receivePacket.getPort());
receiverSocket.send(ackPacket2);
System.out.println("Sent acknowledgment ACK for the received email.");
String fileName = "ReceivedEmails/email_" + System.currentTimeMillis() + ".txt";
try (FileOutputStream fos = new FileOutputStream(fileName)) {
fos.write(receivedEmail.getBytes());
System.out.println("Saved received email to file: " + fileName);
} catch (IOException e) {
System.err.println("Error writing the received email to a file: " + e.getMessage());
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (receiverSocket != null && !receiverSocket.isClosed()) {
receiverSocket.close();
}
}
}
}