Android: java.net.DatagramSocket.bind: Недопустимое исключение аргумента

Справочная информация. Я пишу простое приложение UDP для ping бета-сервера, с которым я управляю каждую минуту или около того, чтобы сообщить мне, что он все еще запущен (я не могу включить ping на сервере для тех, кому интересно). Я планирую запустить это на своем телефоне, чтобы предупредить меня, когда сервер больше не отвечает.

Я пытаюсь использовать, казалось бы, простой java.net.DatagramSocket как таковой:

try { socket = new DatagramSocket(); socket.bind(null); } catch (SocketException e) { System.out.println(e.toString()); throw e; } 

Позвольте мне также сказать, что я разрешил разрешения Интернета через манифест android, и если я удалю предложение uses, чтобы сделать это, я получаю ошибку с разрешениями, поэтому я уверен, что работает нормально. Когда я загружаю этот код на Android Virtual Device (AVD) и выполняю его, в вызове bind () мне представлено это исключение:

03-17 19: 07: 39.401: INFO / System.out (338): java.net.BindException: недопустимый аргумент

Согласно этой документации нулевой аргумент правильный:

Public void bind (SocketAddress localAddr)

С: API уровня 1

Привязывает этот сокет к локальному адресу и порту, указанному localAddr. Если это значение равно null, используется любой свободный порт на действительном локальном адресе .

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

  ArrayList<NetworkInterface> allInterfaces = Collections.list(NetworkInterface.getNetworkInterfaces()); NetworkInterface eth = allInterfaces.get(0); InetSocketAddress addr = new InetSocketAddress(eth.getInetAddresses().nextElement(), port); try { socket = new DatagramSocket(); socket.bind(addr); } catch (SocketException e) { System.out.println(e.toString()); throw e; } 

Когда я просматриваю код, он отлично работает, и я вижу два IP-адреса на AVD, но я получаю то же самое исключение в вызове bind (). Кто-нибудь видит, что я могу потерять? Я продолжу исследования и, надеюсь, опубликую решение своей проблемы, но я надеюсь, что кто-то там сможет сократить это для меня.

[Отредактировано: если вы видели мой предыдущий ответ, я сделал классическую ошибку отладки при изменении двух переменных в одном тесте, а другой решил мою проблему.]

Я нашел проблему. Это то, как я объявляю DatagramSocket, который вызывает проблемы. Если я использую DatagramChannel, чтобы открыть DatagramSocket следующим образом, вызов bind () будет успешным.

  DatagramChannel channel = DatagramChannel.open(); DatagramSocket socket = channel.socket(); 

Я тоже наткнулся на эту проблему и нашел причину: если вы вызываете конструктор без параметров без функции new DatagramSocket() , это создает «сокет datagram UDP, который привязан к любому доступному порту на локальном хосте с использованием подстановочного адреса» (as В документах API). Таким образом, это означает, что Socket уже связан. Мое «исправление» для этого заключается в следующем:

  SocketAddress socketAddress = new SocketAddress(yourInetAddress, yourPort); DatagramSocket serverSocket = new DatagramSocket(null); serverSocket.bind(socketAddress); 

Это явно создает несвязанный Socket (через конструктор DatagramSocket (SocketAddress localAddr) ), что позволяет привязывать Socket по очереди.

Это, вероятно, более элегантное решение, чем создание ненужного канала.

PS: Как ни странно, здесь DatagramSocket отличается от TCP ServerSocket : ServerSocket конструктор последнего создаст несвязанный ServerSocket, не инициирующий эту проблему.

Intereting Posts
SetOutputFormat вызывается в недопустимом состоянии: 4 (где и почему) Добавить пользовательский вид справа от панели инструментов Как автоматически увеличить количество проектов Android в Eclipse (предпочитайте портативное решение) Размер предварительного просмотра для сканера штрих-кода от зрения api Gradle: как запустить контрольно-измерительный тест для класса Правильный шаблон ViewHolder реализован в пользовательском CursorAdapter? Тип ввода для экрана редактирования EditText? Как отображать CalendarView в AlertDialog? Какой макет должен использоваться для отображения «нижнего колонтитула» в зависимости от остальной части содержимого экрана ObjectInputStream дает мне пустой объект (но прочитанный файл не пуст) Равномерная ширина столбцов Android GridLayout Android: Facebook API для публикации Могу ли я установить PIN-код для Bluetooth из своего приложения на Android? Повреждения Leakcanary с Firebase от Google Content_URI в поставщике контента