地址重用不适用于新的Java Runtime Environment

时间:2014-12-29 07:49:14

标签: java client-server bind reusability

我使用以下代码检查地址可重用性: -

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






}

}

这在Windows 7,64bit上运行良好 我使用的是JRE 7U5 [1.7 Update 5] 32Bit版本。 [考虑到服务器已在127.0.0.1:4000上运行]

但是当我尝试使用更新版本的JRE时,就像我检查JRE 7U60 32位和JRE 7U72 64位一样,它会产生JVM_Bind异常。 这基本上否定了使用setReuseAddress(true)OPTION。

的整个目的

请帮助解决此问题。

谢谢&此致

1 个答案:

答案 0 :(得分:0)

setReuseAddress的javadoc说:

  

当TCP连接关闭时,连接可能会在连接关闭后的一段时间内保持超时状态(通常称为TIME_WAIT状态或2MSL等待状态)。对于使用众所周知的套接字地址或端口的应用程序,如果在涉及套接字地址或端口的超时状态中存在连接,则可能无法将套接字绑定到所需的SocketAddress。

     

在使用bind(SocketAddress)绑定套接字之前启用SO_REUSEADDR允许套接字绑定,即使先前的连接处于超时状态。

但是你所做的与这个用例不匹配。当其他一些套接字关闭时,您不会尝试绑定。实际上,当另一个套接字打开时,你正试图绑定。


让我感到困惑的是为什么你的测试实际上适用于较旧的JRE。它可能是一个JVM错误......