Сброс соединения сервера Java с клиентом - PullRequest
0 голосов
/ 20 ноября 2018

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

Фрагмент сервера:

private void initServer() throws IOException {
    while (true) {
        ServerSocket server = new ServerSocket(55555);
        Socket fromclient = server.accept();

        InputStream sin = fromclient.getInputStream();
        OutputStream sout = fromclient.getOutputStream();

        DataInputStream in = new DataInputStream(sin);
        DataOutputStream out = new DataOutputStream(sout);

        String line = in.readUTF();

        if (line.equals("new file")) {
            long fileSize = in.readLong();

            tempSavedFile = new File("/home/evgeniy/Files/Downloads/temp");

            tempSavedFile.createNewFile();
            try (FileOutputStream fos = new FileOutputStream(tempSavedFile)) {
                int t;
                for (int i = 0; i < fileSize; i++) {
                    t = sin.read();
                    fos.write(t);
                }
            }

            if (checkPadding(tempSavedFile)) {
                out.writeInt(PADDING_OK_RESPONSE);
            } else {
                out.writeInt(PADDING_ERROR_RESPONSE);
            }
            out.flush();
        }
        out.close();
        in.close();
        sout.close();
        sin.close();
        fromclient.close();
        server.close();
    }
}

Класс клиентакоторый вызывает новый поток для цикла

for (byte i = 0; i < 2; i++) {
Callable callable = new FileSender(tempFile);
        FutureTask<Integer> ftask = new FutureTask<>(callable);
        Thread thread = new Thread(ftask);            
        thread.start();

        int response = 3244;
        try {
            response = ftask.get();
        } catch (InterruptedException | ExecutionException ex) {
            Logger.getLogger(FXMLController.class.getName()).log(Level.SEVERE, null, ex);
        }
        putMessage(String.valueOf(response));

Поток, вызываемый клиентом:

public Integer call() throws Exception {
    Socket socket = new Socket(address, serverPort);
    InputStream sin = socket.getInputStream();
    OutputStream sout = socket.getOutputStream();
    DataInputStream in = new DataInputStream(sin);
    DataOutputStream out = new DataOutputStream(sout);

    out.writeUTF("new file");
    out.flush();

    out.writeLong(file.length);
    out.flush();

    sout.write(file);
    sout.flush();

    System.out.println(socket.isConnected());
    int response = in.readInt();
    System.out.println("--------RESP="+response);

    out.close();
    in.close();
    sin.close();
    sout.close();
    socket.close();
    return response;
}

Как вы можете видеть, я отправляю два файла и получаю этовывод консоли на клиентское приложение:

true
--------RESP=200
true
ноя 20, 2018 5:16:36 PM com.evgeniy_mh.paddingoracle.FXMLController SendFileToServer
SEVERE: null
java.util.concurrent.ExecutionException: java.net.SocketException: Connection reset

Кроме того, я не понимаю, почему сокет в порядке, но

int response = in.readInt();

вызывает исключение сброса соединения.

1 Ответ

0 голосов
/ 20 ноября 2018

Ваш код создает новый ServerSocket, а затем закрывает созданный сокет сервера для каждого отдельного запроса, который он обрабатывает.Код не использует один и тот же экземпляр ServerSocket для обслуживания нескольких запросов.


Похоже, что ошибка сброса соединения вызвана тем, что, когда второй запрос создает соединение через сокет с сервером, существующий ServerSocket закрывается и воссоздается на том же порту, ведущем ксоединение сбрасывается.Для начала попробуйте удалить создание ServerSocket вне цикла while.

private void initServer() {
    try (ServerSocket server = new ServerSocket(5555)) {
        while (true) {
            Socket fromclient = server.accept();

        ... // remaining code

            fromclient.close();
        }
    } catch (IOException ioe) {
        // handle failures
    }
}

try-with-resources обрабатывает вызов .close() на сокете сервера AutoCloseable.


Также обратите внимание, что запросы будут обрабатываться последовательно в одном потоке вашего кода.Обычно Socket, полученный для соединения из ServerSocket#accept() (или потоков, полученных из него), передается в отдельный поток для обработки, в отличие от вашего кода, который обрабатывает запросы последовательно.

...