web-dev-qa-db-ja.com

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)

これはそれを実行するコードです。 new 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);
            }
        }
20
Sean Kilb

バインドする前に_SO_REUSEADDR_を設定する必要があります。コンストラクタでポートを指定しないでください。代わりに DatagramSocket(null) を使用して非バインドソケットを作成し、オプションを設定してから bind() を明示的に指定します。

17

Seanがコードを要求したので、Nikolaの回答を次のコードに翻訳しました。これは、役立つ場合に備えて、アプリで使用しているものと同様です。

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

私が直面した別の理由、

外部スレッドからソケットを使用するメソッドにアクセスする場合は、スレッドが同時にメソッドに2回以上アクセスしないようにする必要があります(または、言い換えると、ソケットが複数作成されないようにする必要があります。時間)、そして DatagramSocketの送信メソッドと受信メソッドはスレッドセーフです にもかかわらず、DatagramSocketオブジェクトの構築はそうではないので、作成できるメソッドを同期するだけですDatagramSocketソケット:

synchronized public void my_datagram_socket() throws Exception{

  // create the socket
  // operations through the socket
  // whatever you want

}
0
Muhammed Refaat