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

我面临的另一个原因,

如果您从外部线程访问使用套接字的方法,则必须确保该线程不会在同一时间多次访问该方法(或者换句话说,不会创建多个套接字time),尽管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 回答