Address reuse not working on new Java Runtime Envi

2019-01-29 01:54发布

I am using the following Code for Checking Address Resusability:-

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;


public class CheckBind {

public static void main(String[] args) {

    Thread serverThread = new Thread(new Runnable() {

        @Override
        public void run() {
            try
            {
                ServerSocket server = new ServerSocket();
                server.setReuseAddress(true);
                server.bind(new InetSocketAddress("127.0.0.1", 2000));
                System.out.println("Server Listen: "+server.getLocalSocketAddress());

                while(true)
                {
                    Socket client = server.accept();
                    System.out.println(""+client.getRemoteSocketAddress());
                    System.out.println(""+client.getLocalSocketAddress());
                }
            } 
            catch (IOException e) 
            {
                e.printStackTrace();
            }

        }
    });

    serverThread.start();

    try {
        Thread.sleep(5000);
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    while(true)
    {
        Socket client = new Socket();
        try 
        {
            client.setReuseAddress(true);
            client.bind(new InetSocketAddress("127.0.0.1", 2000));
            client.connect(new InetSocketAddress("127.0.0.1",4000));
            System.out.println("Client Connect: "+client.getRemoteSocketAddress());
            break;
        } 
        catch (IOException e) 
        {
        // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }






}

}

This worked fine on Windows 7, 64bit And I used JRE 7U5 [1.7 Update 5] 32Bit Version. [Considering A Server is already Running on 127.0.0.1:4000]

But When I try the same with newer versions of JRE , like I checked on JRE 7U60 32bit and JRE 7U72 64bit it gives a JVM_Bind Exception. Which basically negates the whole purpose of using setReuseAddress(true) OPTION.

Kindly help on how to fix this issue.

Thanks & Regards

1条回答
姐就是有狂的资本
2楼-- · 2019-01-29 02:10

The javadocs for setReuseAddress say:

When a TCP connection is closed the connection may remain in a timeout state for a period of time after the connection is closed (typically known as the TIME_WAIT state or 2MSL wait state). For applications using a well known socket address or port it may not be possible to bind a socket to the required SocketAddress if there is a connection in the timeout state involving the socket address or port.

Enabling SO_REUSEADDR prior to binding the socket using bind(SocketAddress) allows the socket to be bound even though a previous connection is in a timeout state.

But what you are doing does not match this use-case. You are not attempting to bind while some other socket is closing. You are actually trying to bind while another socket is open.


What puzzles me is why your test actually worked on older JREs. It might be a JVM bug ...

查看更多
登录 后发表回答