I changed the example code here for Client and Server My Client:
public class Client { public static void main(String[] args) { int n=10000; SocketTest [] st= new SocketTest[n]; for(int i=0;i<n;i++) st[i]= new SocketTest("hi"); for(int i=0;i<n;i++) new Thread(st[i]).start(); } } class SocketTest implements Runnable { private String message = ""; private Selector selector; private int i; public SocketTest(String message){ this.message = message; } @Override public void run() { SocketChannel channel; try { selector = Selector.open(); channel = SocketChannel.open(); channel.configureBlocking(false); channel.register(selector, SelectionKey.OP_CONNECT); channel.connect(new InetSocketAddress("127.0.0.1", 8511)); while (!Thread.currentThread().isInterrupted()){ selector.select(); Iterator<SelectionKey> keys = selector.selectedKeys().iterator(); while (keys.hasNext()){ SelectionKey key = keys.next(); keys.remove(); if (!key.isValid()) continue; if (key.isConnectable()){ connect(key); System.out.println("I am connected to the server"); } if (key.isWritable()){ write(key); } if (key.isReadable()){ read(key); } } } } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } finally { close(); } } private void close(){ try { selector.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } private void read (SelectionKey key) throws IOException { SocketChannel channel = (SocketChannel) key.channel(); ByteBuffer readBuffer = ByteBuffer.allocate(1000); readBuffer.clear(); int length; try{ length = channel.read(readBuffer); } catch (IOException e){ System.out.println("Reading problem, closing connection"); key.cancel(); channel.close(); return; } if (length == -1){ System.out.println("Nothing was read from server"); channel.close(); key.cancel(); return; } readBuffer.flip(); byte[] buff = new byte[1024]; readBuffer.get(buff, 0, length); //length=buff.length; String fromserver = new String(buff,0,length,"UTF-8"); length = fromserver.length(); System.out.println("Server said: "+fromserver); key.interestOps(SelectionKey.OP_WRITE); } private void write(SelectionKey key) throws IOException { SocketChannel channel = (SocketChannel) key.channel(); i++; message = "location now "+i; try{ Thread.sleep(5000); } catch(InterruptedException ie) { System.out.println(""+ie); } channel.write(ByteBuffer.wrap(message.getBytes())); // lets get ready to read. key.interestOps(SelectionKey.OP_READ); } private void connect(SelectionKey key) throws IOException { SocketChannel channel = (SocketChannel) key.channel(); try { if(!channel.finishConnect()) System.out.println("* Here *"); } catch(ConnectException e) { System.out.println("BP 1"); e.printStackTrace(); //channel.close(); //key.cancel(); //return; } /*if (channel.isConnectionPending()){ while(!channel.ffinishConnect()){ System.out.println("not connected"); } }*/ channel.configureBlocking(false); channel.register(selector, SelectionKey.OP_WRITE); } }
I create several clients on one computer, creating several threads. The number of threads is determined by the value of n. When I start a small number of clients, I do not experience any problems, but as soon as I start with n as 500, i.e. 500 client threads, some threads work correctly, but in some cases I encounter this: java.net.ConnectException: Connection refused: no further information at sun.nio.ch.SocketChannelImpl.checkConnect(Native Method) at sun.nio.ch.SocketChannelImpl.finishConnect(Unknown Source) at SocketTest.connect(Client.java:143) at SocketTest.run(Client.java:61)
Line 143: if(!channel.finishConnect()) Therefore, when I read the documentation for this method, it says that it throws:
NoConnectionPendingException . If this channel is not connected and the connection operation has not been initiated.
ClosedChannelException . If this channel is closed.
AsynchronousCloseException . If another thread closes this channel during a connection operation.
ClosedByInterruptException - if another thread interrupts the current thread during the connection operation, thereby closing the channel and setting the current thread interrupt status.
IOException . If any other I / O error has occurred.
But the exception is ConnectException. I tried to catch it, but it does not fall into the catch block.
Any help would be appreciated. Thank you EDIT: I am working on windows. I tried to change the value of n by looking at how many clients were created and how many threw exceptions, and these are the results (I know that I wait more time after each test will allow more open sockets, since after each test scokets will be released after TIME_WAIT ):
n clients connected(by keeping a count at server) 1000 522 2000 568 3000 626 4000 600 (maybe I gave less time before successive runs) 5000 1345 6000 1389 It bothers me how to connect only to these many clients. Can anybody offer the best reading recommendations for Client Server NIO.
EDIT 2
As mentioned in his EJP comment, the Backlog Queue window is full. I changed the client code to generate 100 threads and then sleep for 5 seconds, and thus there wasnβt much queue load, and most of the connection was successful (however, still, when 10,000 connections still failed).