TCP套接字IOException绑定失败:EADDRINUSE(地址已在使用中)

时间:2016-05-22 07:22:49

标签: java android sockets tcp

在看到有关此错误的几篇帖子后,我真的不明白为什么我有时会遇到此异常

我在这里看到几条帖子建议在套接字上绑定一个循环,但我认为它应该执行一次并且在其他地方出现问题。

这是我的代码:

 public ServerNetworkThread()
    {
        setName("ServerNetworkThread");
        _port = Logics.getInstance().getSharedPrefsManager().getInt(SharedPreferencesManager.SERVER_PORT_KEY, Consts.SERVER_PORT);
    }

    public void setHandler(Handler h)
    {
        _handler = h;
    }

    @Override
    public void run()
    {    
        _isWorking = true;
        try
        {
            _serverSocket = new ServerSocket();
            _serverSocket.setReuseAddress(true);
            _serverSocket.bind(new InetSocketAddress(_port));

            while (_isWorking)
            {
                _socket = _serverSocket.accept();
                _socket.setSoTimeout(Consts.CLIENT_SOCKET_TIMEOUT);
                readDataTest();
            }    
        }
        catch (SocketTimeoutException e)
        {
            e.printStackTrace();
            Logger.d("anton", e.getMessage());
        }
        catch (IOException e)
        {
            e.printStackTrace();
            Logger.d("anton", "server thread IOException" + e.getMessage());
        }

    }

    private void readDataTest() throws IOException
    {
        //          BufferedReader inFromClient = new BufferedReader(new InputStreamReader(_socket.getInputStream(),Charset.forName("UTF-16LE")));
         //          BufferedReader inFromClient = new BufferedReader(new InputStreamReader(_socket.getInputStream(),Charset.forName("UTF-16LE")));
        InputStream iStream = _socket.getInputStream();
        InputStreamReader in = new InputStreamReader(iStream, Charset.forName("UTF-16LE"));
        DataOutputStream outToClient = new DataOutputStream(_socket.getOutputStream());
        char[] buf = new char[1024];
        int lettersCount = in.read(buf, 0, buf.length);
        String request = new String(buf,0,lettersCount);
//      request = request.split(Consts.EOF)[0];
        Log.d("test","server got request="+request);

        String responseStr = parseResponse(request);
        byte[] response = responseStr.getBytes("UTF-16LE");
        outToClient.write(response);
        outToClient.flush();
        outToClient.close();
        in.close();
        _socket.close();
    }

这是我的例外:

W/System.err( 1433): java.net.BindException: bind failed: EADDRINUSE (Address already in use)
W/System.err( 1433):    at libcore.io.IoBridge.bind(IoBridge.java:89)
W/System.err( 1433):    at java.net.PlainSocketImpl.bind(PlainSocketImpl.java:150)
W/System.err( 1433):    at java.net.ServerSocket.bind(ServerSocket.java:319)
W/System.err( 1433):    at java.net.ServerSocket.bind(ServerSocket.java:282)
W/System.err( 1433):    at com.example.visionixpanel.logics.network.ServerNetworkThread.run(ServerNetworkThread.java:61)
W/System.err( 1433): Caused by: libcore.io.ErrnoException: bind failed: EADDRINUSE (Address already in use)
W/System.err( 1433):    at libcore.io.Posix.bind(Native Method)
W/System.err( 1433):    at libcore.io.ForwardingOs.bind(ForwardingOs.java:40)
W/System.err( 1433):    at libcore.io.IoBridge.bind(IoBridge.java:87)
W/System.err( 1433):    ... 4 more

这条线被抛出:

 _serverSocket.bind(new InetSocketAddress(_port));

更新

我也有这段代码:

public void stopThread()
{
    _isWorking = false;
    try
    {
        if (_serverSocket != null)
        {
            _serverSocket.close();
        }
        if (_socket != null)
        {
            _socket.close();
        }
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }
}

可能与清理线程套接字资源有关吗?

1 个答案:

答案 0 :(得分:1)

  

我真的不明白为什么有时候我会得到这个例外

您绑定的端口已在使用中。

  

我在这里看到几条帖子建议在套接字上绑定一个循环,但我认为它应该执行一次并且在其他地方出现问题。

我同意。问题是其他一些进程已经在使用该端口。可能是例如事先调用您的应用程序。确保它已退出。如果不是这样,您将不得不找到它是什么过程并采取适当的补救措施,或使用不同的端口号。

我发现你已经在使用setReuseAddress(true)来解决最常见的情况。

  

可能与清理线程套接字资源有关吗?

没有

相关问题