// ClientFull.java
import java.io.*;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
import java.util.List;
import java.util.ArrayList;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
public class ClientFull {
private static final int SERVER_PORT = 12345;
private static final String DOWNLOAD_DIRECTORY = "files";
private static final String UPLOAD_DIRECTORY = "upload_files";
private static final String SERVERS_FILE = "servers.txt";
public static void main(String[] args) {
createDirectoryIfNotExists(DOWNLOAD_DIRECTORY);
createDirectoryIfNotExists(UPLOAD_DIRECTORY);
populateUploadDirectory(); // For demonstration purposes in client 'upload_files' dir
List<String> serverAddresses = readServerAddressesFromFile();
if (serverAddresses.isEmpty()) {
System.out.println("No server addresses found in " + SERVERS_FILE + ". Please add server addresses to this file.");
return;
}
for (String serverAddress : serverAddresses) {
System.out.println("\n--- Connecting to server: " + serverAddress + " ---");
try (Socket socket = new Socket(serverAddress, SERVER_PORT);
DataInputStream dataInputStream = new DataInputStream(socket.getInputStream());
DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream())) {
System.out.println("Connected to server: " + serverAddress);
sendFilesToServer(dataOutputStream); // Send files to server first
receiveFilesFromServer(dataInputStream); // Then receive files from server
System.out.println("--- Completed operations with server: " + serverAddress + " ---\n");
} catch (UnknownHostException e) {
System.err.println("Unknown host: " + serverAddress + ". Skipping to next server.");
} catch (IOException e) {
System.err.println("Could not connect to server " + serverAddress + " or IO error: " + e.getMessage() + ". Skipping to next server.");
}
}
System.out.println("\n--- All server operations completed. ---");
}
private static List<String> readServerAddressesFromFile() {
List<String> addresses = new ArrayList<>();
File serversFile = new File(SERVERS_FILE);
if (!serversFile.exists()) {
System.out.println(SERVERS_FILE + " not found. Creating empty file.");
try {
serversFile.createNewFile();
} catch (IOException e) {
System.err.println("Error creating " + SERVERS_FILE + ": " + e.getMessage());
}
return addresses; // Return empty list if file doesn't exist or cannot be created
}
try (BufferedReader reader = new BufferedReader(new FileReader(serversFile))) {
String line;
while ((line = reader.readLine()) != null) {
line = line.trim();
if (!line.isEmpty() && !line.startsWith("#")) { // Ignore empty lines and comments
addresses.add(line);
}
}
} catch (IOException e) {
System.err.println("Error reading " + SERVERS_FILE + ": " + e.getMessage());
}
return addresses;
}
private static void createDirectoryIfNotExists(String dirName) {
File directory = new File(dirName);
if (!directory.exists()) {
directory.mkdirs();
}
}
// Create some dummy files for testing if the directory is empty
private static void populateUploadDirectory() {
File filesDir = new File(UPLOAD_DIRECTORY);
if (filesDir.list().length == 0) {
for (int i = 1; i <= 3; i++) {
File dummyFile = new File(filesDir, "client_file" + i + ".txt"); // Differentiate client files
if (!dummyFile.exists()) {
try (FileWriter writer = new FileWriter(dummyFile)) {
writer.write("This is client file number " + i + ".");
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
private static void sendFilesToServer(DataOutputStream dataOutputStream) throws IOException {
List<File> filesToSend = getFileList(UPLOAD_DIRECTORY);
dataOutputStream.writeInt(filesToSend.size()); // Send number of files
System.out.println("Sending " + filesToSend.size() + " files to server.");
for (File fileToSend : filesToSend) {
dataOutputStream.writeUTF(fileToSend.getName()); // Send file name
dataOutputStream.writeLong(fileToSend.length()); // Send file size
try (FileInputStream fileInputStream = new FileInputStream(fileToSend)) {
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = fileInputStream.read(buffer)) != -1) {
dataOutputStream.write(buffer, 0, bytesRead);
}
}
dataOutputStream.flush();
System.out.println("File sent to server: " + fileToSend.getName());
}
System.out.println("All files sent to server.");
}
private static void receiveFilesFromServer(DataInputStream dataInputStream) throws IOException {
// Receive file list
int fileCount = dataInputStream.readInt();
System.out.println("Number of files to download from server: " + fileCount);
String[] fileNames = new String[fileCount];
for (int i = 0; i < fileCount; i++) {
fileNames[i] = dataInputStream.readUTF();
System.out.println("File to download from server: " + fileNames[i]);
}
// Download files
for (int i = 0; i < fileCount; i++) {
String originalFileName = dataInputStream.readUTF(); // Get original filename from server
long fileSize = dataInputStream.readLong();
System.out.println("Downloading file from server: " + originalFileName + ", size: " + fileSize + " bytes");
byte[] fileContent = new byte[(int) fileSize]; // Read all content to calculate hash
dataInputStream.readFully(fileContent); // Ensure all bytes are read
String sha256Hash = calculateSHA256(fileContent);
String fileExtension = getFileExtension(originalFileName);
String hashedFileName = sha256Hash + "." + fileExtension;
File downloadedFile = new File(DOWNLOAD_DIRECTORY, hashedFileName);
try (FileOutputStream fileOutputStream = new FileOutputStream(downloadedFile)) {
fileOutputStream.write(fileContent); // Write from the content buffer
}
System.out.println("File downloaded and saved as: " + hashedFileName);
}
String downloadStatus = dataInputStream.readUTF();
if ("DOWNLOAD_COMPLETE".equals(downloadStatus)) {
System.out.println("Download completed successfully.");
} else {
System.out.println("Download status: " + downloadStatus);
}
}
private static List<File> getFileList(String directoryPath) {
List<File> files = new ArrayList<>();
File directory = new File(directoryPath);
File[] fileArray = directory.listFiles();
if (fileArray != null) {
for (File file : fileArray) {
if (file.isFile()) {
files.add(file);
}
}
}
return files;
}
private static String calculateSHA256(byte[] fileContent) {
try {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] hashBytes = digest.digest(fileContent);
StringBuilder hexString = new StringBuilder();
for (byte hashByte : hashBytes) {
String hex = Integer.toHexString(0xff & hashByte);
if (hex.length() == 1) hexString.append('0');
hexString.append(hex);
}
return hexString.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace(); // Handle exception properly in real app
return null;
}
}
private static String getFileExtension(String filename) {
if (filename == null || filename.lastIndexOf('.') == -1) {
return "dat"; // default extension if no extension found
}
return filename.substring(filename.lastIndexOf('.') + 1);
}
}