2009-12-10 2 views
1

У меня есть приложение, которое открывает сокеты datagram и отправляет различные процессы ... иногда это приложение запускает другой процесс (используя ProcessBuilder), который также выполняет некоторую сетевую связь ...Иногда пакеты передаются только после завершения процесса? [Java]

Теперь, шутка заключается в том, что запущенный процесс будет «иногда» получать сообщения только после прекращения основного приложения ... ИЛИ иногда он будет отправляться на X, но они будут доставлены только тогда, когда основное приложение будет остановлено ...

I ' я понятия не имею, что происходит ... кто-нибудь когда-либо слышал о чем-то подобном? Пакеты передаются только при остановке процесса?

+0

Вы хотите сказать, что пакеты не будут отправлены до тех пор, пока вы не убьете процесс, даже если вы ждете вечность? * Или *, вы имеете в виду, что иногда возникает небольшая задержка после того, как процесс завершится нормально до получения пакетов. – erickson

+0

Подождите вечно ... но убив основной процесс, в 99% случаев все сообщения входят вместе ... – Shaitan00

+0

Что такое потоки, когда приложение «заблокировано» (т. Е. Не отправляет созданные пакеты) ? Вместо того, чтобы убивать родительское приложение, получить его дамп потока и посмотреть, что все ждет. – PSpeed

ответ

2

Прошло некоторое время, когда я программировал сокеты на Java, но я помню, что вы должны явно очистить сокет, чтобы «принудительно» отправить все данные. Это будет сделано после закрытия сокета для вас, что объяснит ваше наблюдаемое поведение.

+0

Но я не закончил отправку ... Должен ли я.Закрыть после каждого отправления = новый DataSocket перед каждой отправкой? – Shaitan00

+0

@Shaitan: Он сказал, что «флеш» для принудительной отправки, а не «близко» - упоминание о закрытии было только для того, чтобы сказать, что закрытие делает флеш, и завершение JVM закрывает все открытые дескрипторы процесса. –

0

Вы посмотрели socket.setTcpNoDelay(true);?

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

EDIT: Извините, я думаю, что это только для не-дейтаграммных сокетов. Наверное, не твоя проблема.

+1

OP говорит, что использует дейтаграммы (я думаю, UDP). Поэтому я не думаю, что это будет иметь какой-то эффект. –

0

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

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

EDIT:

Но на самом деле, я думаю, что наиболее вероятной причиной является то, что дочерний процесс блокирует, потому что родительский процесс не читает материал, написанный для вывода ребенка ... пока это уже слишком поздно имеет значения. В качестве эксперимента, добавьте следующие строки в запуске дочернего процесса:

OutputStream os = new FileOutputStream(...); // pick a suitable temp filename 
System.setOut(os); 
System.setErr(os); 

Если этот хак фиксирует вещи, это верный признак того, что это корень проблемы.

+1

Как я должен ПОМОЧЬ? Для DatagramSocket нет .flush() для DatagramSocket, и я не делаю с ним ... но я бы хотел, чтобы сообщение передало его как отправленное, а не все в одной огромной группе, основное приложение убито ... – Shaitan00

0

Является ли процесс ребенка письменным до System.out или System.err? Установили ли вы основной процесс для слива этих потоков после запуска дочернего процесса? Возможно, дочерний процесс просто зашел в тупик, пытаясь распечатать сообщение журнала в потоке блокировки, который не читается. Когда родительское приложение убито, поток становится разблокированным, и все начинает двигаться снова. Это может быть длинный, но я был укушен этим достаточно времени при запуске дочерних процессов, которые я всегда проверяю.

+0

Ya. .. Я обнаружил, что один из сложного пути ... это заставило мое приложение полностью блокировать ... но теперь ... Я передаю .SEND, и он просто не доставлен (они накапливаются где-то), пока приложение убито, тогда они входят в спешке – Shaitan00