Точное обнаружение ошибок отправки сокетов в Java - PullRequest
0 голосов
/ 16 февраля 2012

Я пишу приложение для Android, которое инициализирует DatagramSocket для подключения к серверу, а затем использует бесконечный цикл для периодической (например, каждые 5 секунд) отправки пакетов данных.Код отправки ниже:

DatagramPacket packet = new DatagramPacket(message, message.length);
try {
    socket.send(packet);
}
catch (IOException e) {
    // Log failure and return
}
// Log success

Теперь я могу позволить себе потерять пакет время от времени.Но я хотел бы иметь возможность определять, становится ли сервер недоступным (например, происходит сбой), когда я подключен, и в этом случае я хотел бы сохранить сообщения, которые я отправляю (чтобы отправить их в другое время).Первоначально я думал, что исключение будет выдаваться каждый раз, когда я пытаюсь отправить пакет через этот сокет, и, следовательно, смогу справиться с хранением сообщений в моем блоке catch.На самом деле это частично работает.Я моделирую сбой сервера, просто отключив сервер, и начинаю получать исключения с сообщением sendto failed: ECONNREFUSED (Connection refused) при отправке пакета.Проблема в том, что не каждая попытка отправки вызывает исключение, а только каждую четную попытку - поэтому мой журнал выглядит как

Успех, Ошибка, Успех, Ошибка, ...

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

Мой вопрос: есть ли способ убедиться, что исключение выдается каждый раз, пока сервернедоступен?Или есть какой-то другой способ обнаружить, что другой конец сокета молча отключился?Я пытался проверить socket.isConnected() внутри моего цикла, но он всегда возвращает true.

1 Ответ

3 голосов
/ 17 февраля 2012

DatagramSocket по определению не требуют соединения - вот хорошая страница о различиях между UDP и TCP для потомков. То, что вы получаете какие-либо ошибки вообще, указывает мне, что вы отправляете на сервер в вашей локальной сети, который не отвечает на arps - либо то, что наш шлюз по умолчанию уходит, что менее вероятно. То, что любое из ваших send сообщений возвращает ошибки, очень зависит от ОС и сети, и на IMO не следует полагаться. Это также означает, что если вы установите маршрутизатор между вами и сервером, то none из send методов вернет ошибку, я считаю.

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

Конечно, как только вы начнете идти по этому пути, вы можете рассмотреть возможность использования Jgroups или переключения на TCP / IP. : -)

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