Какое условие вызывает ошибку «Разорванная труба» на другом конце?

У меня есть клиент-серверное приложение, отправляющее данные с телефона Android на планшет — телефонные звонки, SMS, состояние батареи и т. д. Телефон — это клиент, планшет — сервер, и оба запускают службы с частичными вейклоками для их сохранения. жив достаточно долго, плюс у клиента есть PhoneStateListener и BroadcastReceiver для отслеживания вызовов, состояния батареи и т. д.

Дело в том, что оба конца остаются живы, но на каком-то этапе - по моим настройкам логирования около 20 минут - Клиент сообщает, что у меня "Broken Pipe".

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

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

  • Независимо от того, открыт сокет или нет.
  • Независимо от того, открыт ли входной или выходной поток,
  • Являются ли какие-либо из них нулевыми.

К сожалению, все эти условия в порядке, и соединение
все еще активно. Что я должен искать?

Что я хочу сделать, так это то, что после того, как клиент обнаружит «сломанную трубу», сервер тоже сделает это и попытается повторно подключиться.


person Douglas Brett    schedule 30.05.2014    source источник


Ответы (1)


«Сломанный канал» означает, что вы написали в соединение, которое уже было закрыто на другом конце. Иногда это проявляется при записи, а иногда при чтении. Во всех случаях это относится к предыдущей записи.

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

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

person user207421    schedule 30.05.2014
comment
Спасибо за ответ. Сервер не намеренно закрывает сокет, я где-то читал, что соединения сокетов могут быть потеряны через некоторое время из-за спящего режима - может быть, это блокирующий сервер? В настоящее время это цикл while, я мог бы перейти на неблокирующую настройку и настройку Timer & TimerTask вместо этого. Я не понимаю, что поток супервизора, который я запускаю в службе сервера, не может обнаружить какие-либо изменения в состоянии сокета, но обнаруживает, когда он закрыт, когда служба намеренно закрыта. - person Douglas Brett; 31.05.2014