Блокировка Android в connect()

Я пишу приложение для Android, которое подключается к серверу аутентификации для получения IP-адреса и порта другого устройства Android, на котором запущена отдельная серверная программа. Сервер аутентификации отправляет правильную информацию о соединении при отправке запроса. Проблема заключается в том, что клиентское устройство пытается подключиться к серверу Android. Клиент получает правильную информацию и успешно закрывает предыдущие подключения, но зависает при попытке создать новые подключения. Исключения не выдаются, но пользовательский интерфейс не отвечает, и устройство в конечном итоге сообщает, что приложение не отвечает. У меня есть эмулятор, выступающий в роли клиентского устройства, и реальный телефон, выступающий в роли сервера.

Вот часть клиентского кода, на которой он зависает:

Log.i("Socket", "About to open a new socket");
socketChannel = SocketChannel.open(new InetSocketAddress(ip, port));
socketChannel.configureBlocking(false);
socketChannel.register(selector, SelectionKey.OP_READ);
Log.i("Socket", "New socket created and registered");

ip — это String, содержащий IP-адрес сервера. port — номер порта сервера. У меня есть два вызова Log.i(), чтобы найти, где зависает программа. Первый вызов выполняется, а второй нет. Есть ли причина, по которой этот сегмент кода может привести к зависанию приложения?

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


person jakeprogrammer    schedule 28.05.2013    source источник


Ответы (1)


Две возможности.

  1. Вызов connect() находится в середине тайм-аута, который занимает около минуты в зависимости от платформы. Это в основном означает, что цель недоступна. Возможно, вы захотите просмотреть, почему это так. Если вы не контролируете, к каким целям будет подключаться этот код, вы должны сначала перевести канал в неблокирующий режим, затем подключиться, а затем зарегистрировать канал для OP_CONNECT. Если вы пойдете по этому пути, это еще не все, что я добавлю, если потребуется.

  2. У вас есть Selector, работающий в другом потоке, и в настоящее время он заблокирован в select(), что не позволит вам вызвать register(). Решение в этом случае состоит в том, чтобы разбудить селектор перед вызовом register() и убедиться, что поток селектора правильно справляется с нулевым возвратом из select().

person user207421    schedule 28.05.2013
comment
Селектор находится в том же потоке, что и соединение, так что это не так. Каковы некоторые возможные причины, по которым вызов connect() истекает? У меня есть код для целевого устройства, если это поможет. - person jakeprogrammer; 28.05.2013
comment
Я вернулся к коду подключения и добавил дополнительные операторы Log.i(), а также изменил открытие и подключение к другим строкам. Он определенно зависает при подключении () - person jakeprogrammer; 28.05.2013
comment
Так что случай (1) применим. Устройство или промежуточная сеть не отвечает (хотя маршрут существует), - person user207421; 29.05.2013
comment
Есть ли у вас какие-либо предложения о том, как я могу найти проблему? - person jakeprogrammer; 29.05.2013