Сокеты и ObjectInputStreams - PullRequest
       13

Сокеты и ObjectInputStreams

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

У меня есть два приложения, работающие на двух разных машинах, которые обмениваются данными, отправляя Serializable объекты «Message» через реализацию Javas Socket. Каждый из них создает SocketServer, подключается к другому серверу, а затем следующие биты (псевдо-Java, ошибки и сведения о соединении опущены для краткости):

Код получения:

while (true) {
    Object received = oisFromOtherMachine.readUnshared();
    dispatch(received);
}

Отправка кода:

synchronized void sendMessage(Message m) {
    oosToOtherMachine.writeObject(m);
    oosToOtherMachine.flush();
    oosToOtherMachine.reset();
}

Который вызывается довольно регулярно из разных потоков.

Это все работало нормально и до 3 недель назад, когда иногда, в ответ на определенный бит пользовательского ввода, вызов readUnshared будет сбрасываться. До сих пор мы видели «java.lang.IllegalStateException: непрочитанные данные блока» и «java.lang.ClassCast». Исключение: java.util.HashMap не может быть приведен к java.io.ObjectStreamClass ", как изнутри, так и внутри ObjectInputStream.

Это происходит примерно один раз в 5, обычно после того, как две системы работают и разговаривают друг с другом в течение 15 с лишним минут. По разным причинам у нас есть два сетевых кабеля, которые регулярно используются между двумя, один с намоткой и узелком 15 м (пинг 30 мс +), другой около 1 м (пинг <1 мс). Это случалось только по короткому кабелю (и поверьте мне, мы пробовали это по длинному кабелю много раз). </p>

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

Итак. Google не предлагает никаких ошибок в OIS, OOS или Java Sockets, которые могли бы вызвать это, и мои коллеги так же тупы, как и я ... Кто-нибудь видел что-то подобное раньше?

Edit: Спасибо всем за предложения. (-: В заключение я подозреваю, что некоторый несинхронизированный доступ к некоторым объектам состояния журналирования приводит к созданию неработающего графа объектов, что вызывает удушье OIS. Однако это необходимо решить вчера, а также либеральное применение ключевого слова synchronized вместе со следующим мерзость ...

try {/* message loop */ } catch (RuntimeException) { /* resync appstate and continue*/ } 

... будет сделано гораздо быстрее и с гораздо более высокими шансами на успех, чем более разочаровывающие (25 минут +) попытки воспроизвести проблему и связанные с ней царапины.

Ответы [ 4 ]

2 голосов
/ 17 июня 2009

Мои предположения: у вас есть некоторое повреждение данных между двумя машинами; или они работают на разных версиях Java; у вас есть несколько хитрых синглетонов в графе объектов; сбой () на стороне отправителя не работает.

Почему вы используете readUnshared ()?

0 голосов
/ 17 июня 2009

Мое случайное предположение: хотя sendMessage помечено synchronized, у вас есть более одного экземпляра объекта для каждого потока. Или, возможно, у вас есть более одного ObjectOutputStream для каждого Socket OutputStream.

0 голосов
/ 17 июня 2009

Мне кажется, что сетевые данные повреждены.

Может быть, поврежден короткий кабель? Вы пробовали использовать другой короткий кабель

Другая возможность - неисправная сетевая карта или драйвер.

0 голосов
/ 17 июня 2009

Никогда не видел, чтобы это произошло, и я довольно сильно использую Sockets + ObjectStreams.

Я предлагаю вам попробовать новые версии JVM, IllegalStateExceptions глубоко в недрах библиотек базовых классов пахнут странно. Тот факт, что это происходит только при очень быстром соединении почти , делает его похожим на состояние гонки.

Возможно, на этот раз вы "нашли ошибку в GCC"?

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