简体   繁体   中英

Connection refused after connecting 75 clients to server

I had developed a server channel socket using below code:

public class EchoServer {
private static final int BUFFER_SIZE = 1024;

private final static int DEFAULT_PORT = 9090;

private long numMessages = 0;

private long loopTime;

private InetAddress hostAddress = null;

private int port;

private Selector selector;

// The buffer into which we'll read data when it's available
private ByteBuffer readBuffer = ByteBuffer.allocate(BUFFER_SIZE);

int timestamp=0;

public EchoServer() throws IOException {
    this(DEFAULT_PORT);
}

public EchoServer(int port) throws IOException {
    this.port = port;
    hostAddress = InetAddress.getByName("127.0.0.1");
    selector = initSelector();
    loop();
}

private Selector initSelector() throws IOException {
    Selector socketSelector = SelectorProvider.provider().openSelector();

    ServerSocketChannel serverChannel = ServerSocketChannel.open();
    serverChannel.configureBlocking(false);

    InetSocketAddress isa = new InetSocketAddress(hostAddress, port);
    serverChannel.socket().bind(isa);
    serverChannel.register(socketSelector, SelectionKey.OP_ACCEPT);
    return socketSelector;
}

private void loop() {
    for (;true;) {
        try {
            selector.select();
            Iterator<SelectionKey> selectedKeys = selector.selectedKeys()
                    .iterator();
            while (selectedKeys.hasNext()) {
                SelectionKey key = selectedKeys.next();
                selectedKeys.remove();
                if (!key.isValid()) {
                    continue;
                }
                 // Check what event is available and deal with it
                if (key.isAcceptable()) {
                    accept(key);
                } else if (key.isWritable()) {
                    write(key);
                }
            }
            Thread.sleep(3000);
            timestamp+=3;
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(1);
        }



    }
}

private void accept(SelectionKey key) throws IOException {

    ServerSocketChannel serverSocketChannel = (ServerSocketChannel) key.channel();

    SocketChannel socketChannel = serverSocketChannel.accept();
    socketChannel.configureBlocking(false);
    socketChannel.setOption(StandardSocketOptions.SO_KEEPALIVE, true);
    socketChannel.setOption(StandardSocketOptions.TCP_NODELAY, true);
  //  socketChannel.register(selector, SelectionKey.OP_READ);
    socketChannel.register(selector, SelectionKey.OP_WRITE);

    System.out.println("Client is connected");
}

private void write(SelectionKey key) throws IOException {
    SocketChannel socketChannel = (SocketChannel) key.channel();
    ByteBuffer dummyResponse = ByteBuffer.wrap(("ok:" + String.valueOf(timestamp)) .getBytes("UTF-8"));

    socketChannel.write(dummyResponse);
    if (dummyResponse.remaining() > 0) {
        System.err.print("Filled UP");
    }
    System.out.println("Message Sent");
 //   key.interestOps(SelectionKey.OP_READ);
}

}

As you can see I run it on localhost port 9090 . In order to testing the code for heavy connections I developed a test app that each second run a new thread and connect to the server. This is the code of my test app:

    public class Main {

    /**
     * @param args
     */
    public static void main(String[] args) {
        int i = 0;
        try {
            while (i < 10000) {
                RunnableDemo temp = new RunnableDemo("Thread-"
                        + String.valueOf(i));
                temp.start();
                i++;
                Thread.sleep(1000);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

class RunnableDemo implements Runnable {
    private Thread t;
    private String threadName;

    InetAddress host = null;
    int port = 9090;

    RunnableDemo(String name) {
        threadName = name;
        System.err.println("Creating " + threadName);

    }

    public void run() {
        System.err.println("Running " + threadName);
        try {
            SocketChannel socketChannel = SocketChannel.open();

            socketChannel.connect(new InetSocketAddress(host, port));

            while (!socketChannel.finishConnect())
                ;

            System.out.println("Thread " + threadName + " Connected");
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            while (true) {
                if (socketChannel.read(buffer) > 0) {
                    buffer.flip();
                    byte[] bytes = new byte[buffer.limit()];
                    buffer.get(bytes);  
                    System.out.println(threadName+ ":" + new String(bytes));
                    buffer.clear();
                }
            }

        } catch (Exception e) {
            System.out.println("Thread " + threadName + " interrupted.");
            e.printStackTrace();
        }
        System.out.println("Thread " + threadName + " exiting.");
    }

    public void start() {
        System.out.println("Starting " + threadName);
        try {
            host = InetAddress.getByName("127.0.0.1");
            if (t == null) {
                t = new Thread(this, threadName);
                t.start();
            }
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
    }

}

The test application runs but only 75 threads can connect to the server and all thread after 75th shows below exception:

java.net.ConnectException: Connection refused: connect
at sun.nio.ch.Net.connect0(Native Method)
at sun.nio.ch.Net.connect(Unknown Source)
at sun.nio.ch.Net.connect(Unknown Source)
at sun.nio.ch.SocketChannelImpl.connect(Unknown Source)
at net.behboodi.client.RunnableDemo.run(Main.java:48)
at java.lang.Thread.run(Unknown Source)

Is there any limits for number of concurrent connections to the socket? Or is there any limits on using port 127.0.0.1 and local host? The other idea is that maybe a java app or JVM can not create more than 75 thread.

I searched about them all, but do not find any answer that show me what of the above reasons is my main problem and how can I fixed the code so that I can test the app with more than 10000 concurrent thread?

Get rid of the sleep. The Selector already blocks. Sleeping in network code is just literally a waste of time. NB (1) You don't call finishConnect() in blocking mode, (2) you aren't connecting threads to a ServerChannel, you are connecting client sockets to a server socket, (3) your client code doesn't handle end of stream, and (4) this is not an echo server. – EJP

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM