Страницы

Поиск по вопросам

пятница, 27 декабря 2019 г.

Java, проблема с Socket

#java #сокет


Всем привет. 
Может кто сталкивался и подскажет в какую сторону капать? Вопрос по сокетам. 

Есть сервер и клиент. Клиент серверу передает некоторое задание, которое длится 5
минут. После выполнения, сервер дает ответ, что задание выполнено 

sendInfo.writeUTF("FileAutoExchangeUpload");


, при  этом на стороне сервера в логах все хорошо, после отправки ответа, сокет закрывается.
Но на стороне клиента, который ждет ответа 

input = getInfo.readUTF();


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

Java файлы на стороне сервера:

Server.java: (запуск отдельного потока, при подключении клиента)

while (true) {
   try {
        client = server.accept();
    } catch (IOException e) {
        LOG.error("Ошибка подключения клиента! " + e);
    }

    new Thread(new SocketDispatcher(client)).start();
}


SocketDispatcher.java: (элемент нужного задания)

if (input.equals("UploadFileAutoExchange")) {
    kod = getInfo.readUTF();
    sendInfo.writeUTF("Ready!");
    String nameFile = getInfo.readUTF();
    long lengthFile = getInfo.readLong();
    control.setSetting(kod);
    LOG.debug("Получения файла - " + nameFile);
    getFileCp(nameFile, lengthFile);
    LOG.debug("Запуск загрузки данных на ТО!");
    if (new UploadFileCpOnTO(control, kod).upload()) {                   
        LOG.debug("Данные загружены! Отправка ответа об успешной загрузке данных!");
        sendInfo.writeUTF("FileAutoExchangeUpload");
    } else {
        LOG.info("Нет файла выгрузки, код ТО: " + kod);
        sendInfo.writeUTF("noFile");
    }
}

try {
   client.close();
   LOG.debug("Сокет закрыт");
} catch (IOException e) {
   LOG.error("Не могу закрыть сокет клиента! " + e);
}


Java файлы на стороне клиента:

UploadFileAutoExchangeForTO.java (элемент нужного задания)

try {
    String input = getInfo.readUTF();
    if (input.equals("Ready!")) {

        LOG.debug("Получен ответ с ТО о готовности принять файл автообмена, код ТО
- " + kod);
        sendInfo.writeUTF(file.getName());
        sendInfo.writeLong(file.length());

        LOG.debug("Начало передачи файла автообмена - " + file);
        FileInputStream fileReader = new FileInputStream(file);
        byte[] buffer = new byte[64 * 1024];
        int count;

        while ((count = fileReader.read(buffer)) != -1) {
            sendStreamFile.write(buffer, 0, count);
        }
        sendStreamFile.flush();
        fileReader.close();

    }

    LOG.debug("Файл автообмена передан - " + file);
    LOG.debug("Ожидание ответа от ТО, код - " + kod);
    input = getInfo.readUTF(); //Программа ждет в этой строчке ответа от сервера
    LOG.debug("Получен ответ от ТО - " + input);
    if (input.equals("FileAutoExchangeUpload")) {
        socketsList.remove(socket);
        socket.close();
        LOG.debug("Сокет закрыт, код ТО - " + kod);
        return "Код ТО:" + kod + " " + ". Файл загружен на ТО!";
    }

    socketsList.remove(socket);
    socket.close();
    return "Код ТО:" + kod + " " + ". Ошибка. Нет файла выгрузки с ТО! Проверьте
автообмена на ТО!";
} catch (IOException e) {
    return "Код ТО:" + kod + " " + ". Задание прервано!";
}   

    


Ответы

Ответ 1



Точно не скажу, почему так происходит, но одно могу сказать точно. Между сервером и клиентом должны постоянно летать данные (например пакеты с флагом ping в ws), а иначе нельзя точно отловить момент отключения клиента/сервера и соединение простаивает впустую. Поэтому вам нужно либо разрывать соединение и возобновлять его тогда, когда это нужно, либо посылать ping пакеты.

Комментариев нет:

Отправить комментарий