Intereting Posts
Как автоматически удалить приложение Android с устройства перед установкой новой версии Генерировать ошибку Javadoc для Android Studio Android + Arduino Bluetooth Передача данных Вращающееся изображение. Анимационный список или анимированный поворот? (Android) Как отклонить Snackbar, используя собственную кнопку действия? Использование кинжала для инъекций зависимостей на конструкторах Android Лучший способ обнаружить и обработать пользователя НЕАКТИВНОСТЬ Производительность Android: плоский файл с SQLite Как переопределить метод с помощью сочетания клавиш в Android Studio Как изменить цвет трека SwitchCompat Возвращаемое значение из Thread Передача нескольких флагов в намерение в Android ErrnoException: isConnected failed: EHOSTUNREACH (без маршрута к хосту) при изменении сети Wi-Fi с использованием ICS В чем разница между андроидом: lineSpacingExtra и android: lineSpacingMultiplier? Отправьте push на Android с помощью C # с помощью FCM (Firebase Cloud Messaging)

Сообщение об ошибке Android DatagramSocket: EADDRINUSE (адрес уже используется)

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

java.net.BindException: bind failed: EADDRINUSE (Address already in use) at libcore.io.IoBridge.bind(IoBridge.java:89) at java.net.PlainDatagramSocketImpl.bind(PlainDatagramSocketImpl.java:68) at java.net.DatagramSocket.createSocket(DatagramSocket.java:133) at java.net.DatagramSocket.<init>(DatagramSocket.java:78) 

И это код, который его производит. Ошибка возникает в строке с новым DatagramSocket. Как я могу избежать этой ошибки? Спасибо.

 private class ComThread extends Thread { private static final int BCAST_PORT = 8779; DatagramSocket mSocket; InetAddress myBcastIP, myLocalIP; public ComThread() { try { myBcastIP = getBroadcastAddress(); if (D) Log.d(TAG, "my bcast ip : " + myBcastIP); myLocalIP = getLocalAddress(); if (D) Log.d(TAG, "my local ip : " + myLocalIP); if (mSocket == null) { mSocket = new DatagramSocket(BCAST_PORT); mSocket.setReuseAddress(true); mSocket.setBroadcast(true); } } catch (IOException e) { Log.e(TAG, "Could not make socket", e); } } 

Solutions Collecting From Web of "Сообщение об ошибке Android DatagramSocket: EADDRINUSE (адрес уже используется)"

Перед связыванием необходимо установить SO_REUSEADDR . Не указывайте порт в конструкторе – вместо этого создайте несвязанный сокет с DatagramSocket(null) , затем установите параметры, а затем bind() явно.

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

 if (mSocket == null) { mSocket = new DatagramSocket(null); mSocket.setReuseAddress(true); mSocket.setBroadcast(true); mSocket.bind(new InetSocketAddress(BCAST_PORT)); } 

Еще одна причина, по которой я столкнулся,

В случае, если вы получаете доступ к методу, использующему ваш сокет из внешнего потока, вы должны убедиться, что поток не будет обращаться к методу более одного раза в одно и то же время (или другими словами не будет создавать сокет более одного Времени), и несмотря на то, что методы отправки и получения DatagramSocket являются потокобезопасными , создание объекта DatagramSocket не выполняется, поэтому вам нужно просто синхронизировать метод, способный создавать сокет DatagramSocket :

 synchronized public void my_datagram_socket() throws Exception{ // create the socket // operations through the socket // whatever you want }