21

簡単な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);
            }
        }
4

3 に答える 3

31

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

if (mSocket == null) {
    mSocket = new DatagramSocket(null);
    mSocket.setReuseAddress(true);
    mSocket.setBroadcast(true);
    mSocket.bind(new InetSocketAddress(BCAST_PORT));
}
于 2013-02-22T14:44:41.283 に答える
18

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

于 2012-11-26T16:16:43.510 に答える
0

私が直面したもう一つの理由は、

外部スレッドからソケットを使用するメソッドにアクセスする場合は、スレッドが同時にメソッドに複数回アクセスしないようにする必要があります(つまり、ソケットが複数作成されないようにする必要があります)。時間)、DatagramSocketのsendメソッドとreceiveメソッドはスレッドセーフですが、オブジェクトの構築はそうではないため、ソケットDatagramSocketを作成できるメソッドを同期する必要があります。DatagramSocket

synchronized public void my_datagram_socket() throws Exception{

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

}
于 2016-03-06T11:57:00.307 に答える