Случайные ошибки при передаче через сокет

Итак, у меня есть блок кода, который должен отправлять несколько файлов через сокет. То, как я делаю это в цикле for, я открываю сокет -> передаю файл -> закрываю сокет, затем повторяю для других файлов. Указанный код ниже:

for (int i = 0; i < fname.size(); i++) {
            Socket sok = new Socket("localhost",4444);
            PrintStream oos = new PrintStream(sok.getOutputStream());
            oos.println("1");
            try {

                System.out.println(fname.get(i));
                File myFile = new File(path+fname.get(i));
                byte[] mybytearray = new byte[(int) myFile.length()];

                FileInputStream fis = new FileInputStream(myFile);
                BufferedInputStream bis = new BufferedInputStream(fis);
                // bis.read(mybytearray, 0, mybytearray.length);

                DataInputStream dis = new DataInputStream(bis);
                dis.readFully(mybytearray, 0, mybytearray.length);

                OutputStream os = sok.getOutputStream();

                // Sending file name and file size to the server
                DataOutputStream doss = new DataOutputStream(os);
                doss.writeUTF(myFile.getName());
                doss.writeLong(mybytearray.length);
                doss.write(mybytearray, 0, mybytearray.length);
                doss.flush();
                sok.close();
                System.out.println("File " + fname.get(i) + " sent to Server.");

            } catch (Exception e) {
                System.err.println("File does not exist! (May not be true)   Generated Error: "+e);
            } 


            //sendFile(path+fname.get(i));
            //sock.close();
        }
    } catch (Exception e) {
        System.err.println(e);
    }

Теперь происходит то, что клиент не выдает никаких ошибок, фактически он говорит, что файлы были отправлены на сервер. Теперь сервер выдает случайные ошибки. Иногда сервер получает некоторые файлы (никогда не все), а иногда он не получает никаких файлов, и возникающие ошибки также случайны. Ошибки представляют собой одну из следующих ошибок или их комбинацию:

java.io.EOFException
java.io.FileNotFoundException
java.net.SocketException: Connection reset
java.io.UTFDataFormatException

Все эти ошибки на стороне сервера при попытке передачи. Я не знаю, что здесь происходит =/

КОД СЕРВЕРА:

public void receiveFile() {


    try {
        int bytesRead;

        DataInputStream clientData = new DataInputStream(
                clientSocket.getInputStream());

        String fileName = clientData.readUTF();
        OutputStream output = new FileOutputStream((fileName));
        long size = clientData.readLong();
        byte[] buffer = new byte[100000];
        while (size > 0
                && (bytesRead = clientData.read(buffer, 0,
                        (int) Math.min(buffer.length, size))) != -1) {
            output.write(buffer, 0, bytesRead);
            size -= bytesRead;
        }

        output.close();
        clientData.close();

        System.out.println("File " + fileName + " received from client.");
    } catch (IOException ex) {
        System.err.println("Client error. Connection closed.     " +ex);
    }
}

Трассировки стека:

java.io.EOFException
    at java.io.DataInputStream.readUnsignedShort(Unknown Source)
    at java.io.DataInputStream.readUTF(Unknown Source)
    at java.io.DataInputStream.readUTF(Unknown Source)
    at ClientConnection.receiveFile(ClientConnection.java:80)
    at ClientConnection.run(ClientConnection.java:46)
    at java.lang.Thread.run(Unknown Source)

1
Accepted connection : Socket[addr=/127.0.0.1,port=60653,localport=4444]
File LF-statistikkboka(Myers).pdf received from client.
1
java.io.EOFException
    at java.io.DataInputStream.readUnsignedShort(Unknown Source)
    at java.io.DataInputStream.readUTF(Unknown Source)
    at java.io.DataInputStream.readUTF(Unknown Source)
    at ClientConnection.receiveFile(ClientConnection.java:80)
    at ClientConnection.run(ClientConnection.java:46)
    at java.lang.Thread.run(Unknown Source)

File WHAT IS LEFT TO DO.docx received from client.

По запросу код для приема команд от клиента

in = new BufferedReader(new InputStreamReader(
                clientSocket.getInputStream()));
        String clientSelection;
        clientSelection = in.readLine();
        System.out.println(clientSelection);
        while ((clientSelection) != null) {
            switch (clientSelection) {
            case "1":
                receiveFile();
                break;
            case "2":
                String outGoingFileName;
                while ((outGoingFileName = in.readLine()) != null) {
                    sendFile(outGoingFileName);
                }
                break;
            case "3":
                sync();
                break;
            default:
                System.out.println("Incorrect command received.");
                break;
            }
            //in.close();
            break;
        }

person Shamikul Amin    schedule 24.04.2014    source источник
comment
Покажите пожалуйста код сервера - ведь именно там ошибки, да?   -  person Jon Skeet    schedule 24.04.2014
comment
Сделанный. Это функция, которая получает файлы и выдает ошибки.   -  person Shamikul Amin    schedule 24.04.2014
comment
И какие вызовы вызывают исключения? (Что такое трассировка стека?)   -  person Jon Skeet    schedule 24.04.2014
comment
@ShamikulAmin трассировки стека, пожалуйста..   -  person Rod_Algonquin    schedule 24.04.2014
comment
Можете ли вы указать, какая строка является строкой 80 из recieveFile?   -  person tbodt    schedule 24.04.2014
comment
@tbodt String fileName = clientData.readUTF();   -  person Shamikul Amin    schedule 24.04.2014


Ответы (2)


Виновником, вероятно, является несколько строк в клиентском коде:

PrintStream oos = new PrintStream(sok.getOutputStream());
oos.println("1");

Строка «1» будет отправлена ​​через соединение, но для ее получения нет кода сервера, поэтому она путается с именем файла, а имя файла интерпретируется как размер, а данные файла слишком короткие, поэтому вы получаете много исключений. Поскольку значение является константой, похоже, нет смысла передавать строку «1», поэтому удаление этих строк должно исправить хотя бы ее часть.

person tbodt    schedule 24.04.2014
comment
Эта часть работает, она находится в другой части кода, все, что она делает, это то, что это команда, поэтому она может подготовить сервер для получения файла. - person Shamikul Amin; 24.04.2014
comment
Я хотел бы увидеть код, который получает это 1. Проблема может быть там. - person tbodt; 24.04.2014

Вы должны читать строку «1» с помощью BufferedReader, который «украдет» некоторые из следующих данных. Вы должны использовать DataInputStream.readUTF() для чтения команд из потока с тем же DataInputStream, который вы используете для чтения следующего файла, и вы должны использовать DataOutputStream.writeUTF() для записи команды, используя тот же DataOutputStream, который вы используете для отправки файл.

NB нет необходимости читать весь файл в память. Он просто тратит память, увеличивает задержку и не масштабируется. Используйте цикл копирования, такой как ваш цикл приема, и буфер, скажем, 8 КБ.

person user207421    schedule 25.04.2014