使用始终相同端口的多个非同时Java客户端 - 服务器连接

时间:2011-10-17 08:42:53

标签: java sockets reusability connection

我正在尝试测试一个服务器从一个客户端接受连接(每次一个)的场景,使用始终相同的端口(在服务器和客户端)。

目的是让1个客户端应用程序以大于100 / min的速率发送少量数据。很明显的解决方案是在客户端和服务器之间建立一个始终连接的链接,但这是生产工具,这需要对已经实现的代码进行更大的更改。使用我们今天实现的解决方案,我们在TIME_WAIT中总是有+ -1K连接,我想摆脱它们。

我已经实现了一个简单的测试器,代码是:

public class Server {
    public static void main(String[] args) {
        ServerSocket ssock = null;
        try {
            ssock = new ServerSocket();
            ssock.bind(new InetSocketAddress(Common.SERVER_PORT));
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(-1);
        }

        while(true){
            try{
                Socket cSock = ssock.accept();

                BufferedReader reader = new BufferedReader(new InputStreamReader(cSock.getInputStream()));
                reader.readLine();

                PrintWriter writer = new PrintWriter(cSock.getOutputStream());
                writer.println(Common.SERVER_SEND);
                writer.flush();

                reader.close();
                writer.close();
                cSock.close();

            }catch (Exception e) {
                System.out.println(e.getClass().getName() + ": " + e.getMessage());
            }
        }
    }
}


public class Client {

    public static void main(String[] args) throws Exception {
        InetSocketAddress cliAddr = new InetSocketAddress(
                InetAddress.getByName(args[0]), 
                Common.CLIENT_PORT);

        InetSocketAddress srvAddr = new InetSocketAddress(
                InetAddress.getByName(args[1]), 
                Common.SERVER_PORT);

        for(int j=1;j<=50;j++){
            Socket sock = null;
            try{
                sock = new Socket();
                sock.setReuseAddress(true);
                sock.bind(cliAddr);
                sock.connect(srvAddr);

                PrintWriter writer = 
                        new PrintWriter(
                                sock.getOutputStream());

                writer.println(Common.CLIENT_SEND);
                writer.flush();

                BufferedReader reader = 
                        new BufferedReader(
                                new InputStreamReader(
                                        sock.getInputStream()));
                reader.readLine();

            }catch (Exception e) {
                System.out.println(e.getClass().getName() + ": " + e.getMessage());
                System.exit(-1);
            }finally{
                if(sock!=null) sock.close();
                System.out.println("Done " + j);
            }
        }
    }
}

public class Common {
    public static final int SERVER_PORT = 9009;
    public static final int CLIENT_PORT = 9010;
    public static final String CLIENT_SEND = "Message";
    public static final String SERVER_SEND = "OK";
}

执行客户端和服务器时,在Windows主机上,在一次客户端执行中,我总是得到

java.net.ConnectException: Connection timed out

在linux主机中执行客户端和服务器时,在某些客户端执行时,我得到了

java.net.NoRouteToHostException: Cannot assign requested address

我一直在为这种行为而头疼。有人可以告诉我是否有可能做我想做的事,以及我做错了什么?

1 个答案:

答案 0 :(得分:0)

如果你想摆脱TIME_WAIT状态,不要成为接收关闭的对等体。成为发起结束的同伴。在这种情况下,在读取响应后立即关闭连接,让服务器循环查找另一个请求,以便它读取EOF而不是在发送响应后立即关闭连接。然而,这只会使问题变得更糟,因为所有TIME_WAIT状态都将在服务器而不是客户端累积。另一方面,服务器现在被构造为每个连接接受多个请求,因此您所要做的就是调整客户端以使用连接池,并解决所有问题。