Шаг 160.
Язык программирования Java.
Второе клиент-серверное приложение. Серверная часть

На этом шаге мы приведем серверную часть нашего приложения

Вот серверная часть нашего приложения:

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

public class Server {

    public static void main(String[] args) throws IOException {
        try (ServerSocket socket = new ServerSocket(Constants.PORT)) {
            ExecutorService executorService = Executors.newFixedThreadPool(4);

            while (!socket.isClosed()) {
                Socket client = socket.accept();
                executorService.execute(new FileDownloadThread(client));
            }

            executorService.shutdown();
        }
    }

    /**
     * Класс-воркер
     */
    private static class FileDownloadThread extends Thread {

        public static final String ROOT_PATH = "dirs";

        private Socket client;
        private String loginValue;

        public FileDownloadThread(Socket client) {
            this.client = client;
            setDaemon(true);
        }

        @Override
        public void run() {
            try {
        DataInputStream inputStream = new DataInputStream(client.getInputStream());
        DataOutputStream outputStream = new DataOutputStream(client.getOutputStream());

                while (true) {
                  String typeOperation = inputStream.readUTF();

                  if (TypeOperation.LOGIN.name().equals(typeOperation)) {
                      login(inputStream);
                  } else if (TypeOperation.LOGOUT.name().equals(typeOperation)) {
                      break;
                  } else if (TypeOperation.FILES_LIST.name().equals(typeOperation)) {
                      sendFilesList(outputStream);
                  } else if (TypeOperation.DELETE_FILE.name().equals(typeOperation)) {
                      deleteFile(inputStream, outputStream);
                  } else if (TypeOperation.SEND_FILE.name().equals(typeOperation)) {
                      receiveFile(inputStream, outputStream);
                  }
                }

                inputStream.close();
                outputStream.close();

                client.close();

            } catch (IOException ignore) {
            }
        }

        /**
         * Регистрирует заданного пользователя
         *
         * @param inputStream Входной поток
         */
        private void login(DataInputStream inputStream) throws IOException {
            loginValue = inputStream.readUTF();

            Path path = Paths.get(ROOT_PATH + "/" + loginValue + "/");
            if (!Files.exists(path)) {
               Files.createDirectories(Paths.get(ROOT_PATH + "/" + loginValue + "/"));
            }
        }

        /**
         * Отправляет список файлов пользователя
         *
         * @param outputStream Выходной поток
         */
        private void sendFilesList(DataOutputStream outputStream) throws IOException {
            Path path = Paths.get(ROOT_PATH + "/" + loginValue + "/");
            List<String> filesName = Files.list(path)
                    .map(Path::getFileName)
                    .map(Path::toString)
                    .collect(Collectors.toList());

            outputStream.writeInt(filesName.size());
            filesName.forEach(fileName -> {
                try {
                    outputStream.writeUTF(fileName);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            });
            outputStream.flush();
        }

        /**
         * Удаляет заданный файл
         *
         * @param inputStream  Входной поток
         * @param outputStream Выходной поток
         */
        private void deleteFile(DataInputStream inputStream,
                                DataOutputStream outputStream) throws IOException {
            String fileName = inputStream.readUTF();

            Path path = Paths.get(ROOT_PATH + "/" + loginValue + "/" + fileName);
            if (Files.exists(path)) {
                Files.delete(path);

                outputStream.writeUTF("Удаление файла успешно завершено");
            } else {
                outputStream.writeUTF("Такого файла нет");
            }
            outputStream.flush();
        }

        /**
         * Принимает заданный файл
         *
         * @param inputStream  Входной поток
         * @param outputStream Выходной поток
         */
        private void receiveFile(DataInputStream inputStream,
                                 DataOutputStream outputStream) throws IOException {
            String fileName = inputStream.readUTF();
            Path path = Paths.get(ROOT_PATH + "/" + loginValue + "/" + fileName);

            FileOutputStream fileOutputStream = new FileOutputStream(path.toFile());
            long fileSize = inputStream.readLong();
            byte[] buffer = new byte[1024 * 1024];

            while (fileSize != 0) {
                int countRead = inputStream.read(buffer, 0, buffer.length);
                fileSize -= countRead;
                fileOutputStream.write(buffer, 0, countRead);
                fileOutputStream.flush();
            }
            fileOutputStream.close();

            outputStream.writeUTF("Файл скопирован");
            outputStream.flush();
        }
    }
}

Проект можно взять здесь

Предыдущий шаг Содержание