Отправка неограниченного количества файлов с клиента на сервер

Итак, у меня есть домашнее задание из школы, в котором клиент должен отправлять неограниченное количество файлов на сервер. Я сделал свою идею так.

  1. Клиент будет отправлять неограниченное количество файлов на сервер.
  2. Сервер перенаправит файлы, загруженные клиентом, в папку моего сервера wamp.

У меня есть рабочий код, но этот код может отправлять только 1 файл с клиента на сервер. Я также хочу, чтобы имя файла загруженных файлов увеличивалось, потому что в моих кодах используется только 1 имя файла, поэтому, если больше клиентов загрузят свои файлы, они перезапишут старое имя файла.

Например: file01.rar затем загрузить file02.rar и так далее.

Вот мой код сервера:

public void run() {
    filePath = "C:/wamp/www/file.rar";
    byte[] aByte = new byte[1];
    int bytesRead;
    InputStream is = null;
    try {
        is = clientSocket.getInputStream();
    } catch (IOException ie) {
        ie.printStackTrace();
    }
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    if (is != null) {
        FileOutputStream fos = null;
        BufferedOutputStream bos = null;
        try {
            fos = new FileOutputStream(filePath);
            bos = new BufferedOutputStream(fos);
            bytesRead = is.read(aByte, 0, aByte.length);
            do {
                baos.write(aByte);
                bytesRead = is.read(aByte);
            } while (bytesRead != -1);
            bos.write(baos.toByteArray());
            bos.flush();
            bos.close();
        } catch (IOException ie) {
            ie.printStackTrace();
        }
    }
}

Вот мой клиентский код:

BufferedOutputStream bos = null;
            try {
                bos = new BufferedOutputStream(s.getOutputStream());
            } catch (IOException ie) {
                ie.printStackTrace();
            }

            if (bos != null) {
                File uploadFile = new File(clientFacultyUploadTextField.getText());
                byte[] myFileSize = new byte[(int)uploadFile.length()];
                FileInputStream fis = null;
                try {
                    fis = new FileInputStream(uploadFile);
                } catch (FileNotFoundException fife) {
                    fife.printStackTrace();
                }
                BufferedInputStream bis = new BufferedInputStream(fis);
                try {
                    bis.read(myFileSize, 0, myFileSize.length);
                    bos.write(myFileSize, 0, myFileSize.length);
                    bos.flush();
                    bos.close();
                    clientFacultyUploadTextField.setText("Upload complete...");
                } catch (IOException ie) {
                    ie.printStackTrace();
                }
            }

person Patrick Escalona    schedule 03.02.2013    source источник
comment
Первый вопрос о SO и таком приятном форматировании, +1 :)   -  person Abubakkar    schedule 03.02.2013


Ответы (1)


Когда вы отправляете несколько файлов, вам нужно сообщить серверу, когда один файл останавливается и начинается другой файл, чтобы он мог обрабатывать их отдельно.

Есть несколько подходов к этой проблеме. Вот некоторые из них, упорядоченные от простых, но ограниченных до сложных, но впечатляющих:

а) Используйте новое соединение для каждого файла и закройте его после завершения передачи. Это сообщает серверу, что файл закончился. Преимущество этого заключается в том, что вы можете легко расширить его, чтобы разрешить одновременную загрузку нескольких файлов одновременно. Недостаток: когда передача прерывается по какой-либо причине, сервер может не определить это как ошибку и сохранить неполный файл, как если бы он был завершен.

б) Используйте то же соединение, но сообщите серверу длину каждого файла. Вы можете сделать это, начав каждую передачу файла с длины файла в байтах. Таким образом, сервер может прочитать это количество байтов, а затем запустить новый файл. Это, конечно, работает только тогда, когда заранее известен размер файла. Его нельзя использовать при потоковой передаче файлов, которые все еще создаются во время загрузки.

c) Используйте протокол кадрирования. Разделяйте файлы на фрагменты и добавляйте к каждому фрагменту префикс заголовка, который сообщает серверу длину фрагмента и является ли он последним или последуют другие фрагменты. Этот метод имеет некоторые накладные расходы, но это очень расширяемая архитектура, которая позволяет легко добавлять новые функции, добавляя дополнительную информацию в заголовок. Вы можете, например, разрешить мультиплексировать несколько передач по одному соединению, добавив идентификатор передачи в заголовок, прервать и возобновить загрузку, добавив порядковый номер и управляющие коды, специальные кадры-команды, которые сообщают серверу удалить или переименовать файлы, которые у него уже есть, и многое другое. Для вдохновения посмотрите, как работают HTTP и FTP.

person Philipp    schedule 03.02.2013
comment
Я потерялся, с чего мне начать? Я думаю, ваше второе решение было лучшим и самым простым для меня. Скажи мне, правильно ли я поступаю или нет. Я получу длину файла? затем используйте оператор условия, например if (file == fileSize)? затем используйте как логическое завершение и установите для него значение true? как это? - person Patrick Escalona; 04.02.2013