Address reuse not working on new Java Runtime Environment

梦想的初衷 提交于 2019-12-29 09:16:30

问题


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:


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 ...



来源:https://stackoverflow.com/questions/27685259/address-reuse-not-working-on-new-java-runtime-environment

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!