简体   繁体   中英

TCP Socket IOExceptionbind failed: EADDRINUSE (Address already in use)

After seeing several posts about this error, I don't really understand why the sometimes I am getting this exception

I saw several posts here that suggested to do a loop over binding the socket, but I think it should be executed once and there is a problem somewhere else.

This is my code:

 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();
    }

This is my exception:

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

It is thrown by this line:

 _serverSocket.bind(new InetSocketAddress(_port));

update:

I also have this code:

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

Maybe is something to do with cleaning the thread sockets resources?

I don't really understand why the sometimes I am getting this exception

The port you are binding to is already in use.

I saw several posts here that suggested to do a loop over binding the socket, but I think it should be executed once and there is a problem somewhere else.

I agree. The problem is that some other process is already using the port. Possibly for example a prior invocation of your application. Make sure it has exited. If it isn't that, you will have to either find what process it is and take whatever remedial action is appropriate, or use a different port number.

I see you're already using setReuseAddress(true) which solves the most common case of this.

Maybe is something to do with cleaning the thread sockets resources?

No.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM