Address reuse not working on new Java Runtime Environment
Asked Answered
P

1

1

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

Papillon answered 29/12, 2014 at 7:49 Comment(0)
M
0

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

Maryannemarybella answered 29/12, 2014 at 8:4 Comment(2)
Can you suggest some way for achieving this functionality? I am working on a p2p chat application and want to perform a NAT translation to create a direct TCP connection between the 2 users who are behind different NATs.Papillon
I don't think it is possible.Maryannemarybella

© 2022 - 2024 — McMap. All rights reserved.