Java ObjectOutputStream на Socket не flush () ing - PullRequest
5 голосов
/ 28 января 2011

Я работаю над сетевым приложением, написанным на Java, используя ObjectOutputStream и ObjectInputStream поверх Sockets для обмена сообщениями.Мой код выглядит так:

Отправитель:

ObjectOutputStream out;
ObjectInputStream in;
try{
     Socket socket=new Socket(address, port);
     socket.setSoLinger(true, socketLingerTime);
     out=new ObjectOutputStream(socket.getOutputStream());
     out.writeObject(message);
     out.flush();
     out.close();
}catch (variousExceptions)...

Получатель:

Object incoming;
try{
    incoming=myObjectInputStream.readObject();
}catch (SocketException socketError)
{
    if (socketError.getMessage().equals("Connection reset"))
    {
        //this is the exception I get
    }
}

Иногда сообщение проходит нормально, но в других случаях я получаю отмеченное исключение вместообъекта.Разве флеш не должен заставить сообщение перейти на другую сторону?Я как-то неправильно использую функцию?Или это какая-то ошибка в базовом сетевом коде Java / OS?

Спасибо!

ОБНОВЛЕНИЕ:

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

Ответы [ 5 ]

7 голосов
/ 01 марта 2012

Оказывается, проблема была вызвана алгоритмом Нейгла; выходной буфер находится внутри ОС, поэтому он не подвержен сбросу. Решение состоит в том, чтобы отключить алгоритм Nagle с помощью Socket.setTcpNoDelay (true) и буферизировать сообщения на уровне пользователя с помощью BufferedOutputStream.

1 голос
/ 17 июня 2017

В моем случае это глупая проблема, но я трачу впустую 4 часа.Просто нужно использовать outStream.writeln (""); или outStream.write (mess + "\ n"); , поскольку reader.readLine () читаетпока он не найдет '\ n' символа.Так что write () один не будет работать.

0 голосов
/ 28 января 2011

Похоже, что брандмауэр на одном из маршрутизаторов на пути от клиента к серверу по какой-то причине отправляет RST.Я не верю, что с вашим кодом что-то не так.Я пытался воспроизвести проблему, но не смог.

0 голосов
/ 29 января 2011

Сброс соединения может быть вызван записью в соединение, которое уже закрыто на другом конце. Обнаружение может происходить при следующем вводе-выводе или последующем, например читать. Другими словами, это может быть вызвано ошибкой в ​​протоколе вашего приложения. SO_LINGER не поможет, не связывайтесь с этим.

0 голосов
/ 28 января 2011

Вы должны иметь возможность отправлять один объект за соединение.

Чтобы обеспечить правильную очистку ресурсов, лучше всего закрыть сокет и выходной поток.

close () вызовет сброс, поэтому он должен быть избыточным.

Что произойдет, если вы не установите SO Linger?

Какое фактическое исключение вы получаете?

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