NIO client providing exception: java.net.ConnectException: Connection denied: no further information

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

+5
source share
2 answers

ConnectException: connection refused means that nothing is heard on the IP port you tried to connect to, or on some platforms filled with a server listening queue. If he is thrown and you catch him correctly, you will surely catch him. You will need to expand on what is actually happening, and what your actual catch code looks like for further assistance.

However, you have many other problems:

 private void connect(SelectionKey key) throws IOException { SocketChannel channel = (SocketChannel) key.channel(); try { if(!channel.finishConnect()) System.out.println("* Here *"); 

At this point, if finishConnect() returns false, you must return. You should not fail and reregister the channel for OP_WRITE. The connection is still awaiting. Printing "* Here *" also pretty vain. Try printing something meaningful.

  } catch(ConnectException e) { System.out.println("BP 1"); e.printStackTrace(); //channel.close(); 

You must definitely close the channel at this moment. It is useless to humans or beasts.

  //key.cancel(); 

Closing a channel cancels the key. Remove wherever you meet.

  //return; 

As above, you should definitely be back at this point.

  } /*if (channel.isConnectionPending()){ while(!channel.ffinishConnect()){ System.out.println("not connected"); } }*/ 

Get rid of this pile. It is never appropriate to rotate in non-blocking mode. Don't even leave him lying like comments: some idiot may come later and play with his return.

  channel.configureBlocking(false); 

The channel is already in non-blocking mode. Otherwise, you would not be here. Delete

  channel.register(selector, SelectionKey.OP_WRITE); 

Another way to do this: key.interestOps(SelectionKey.OP_WRITE);

Sleeping in network code is literally a waste of time. He does not solve anything.

You assume that write() succeeded completely, and you ignore the account it returns.

You are using pretty poor quality:

  • Similar notes about write() apply as described above.
  • flip() not "like reset".
  • Canceling a key closes the channel.
  • You do not need to clear the brand-new ByteBuffer, but in any case allocating a ByteBuffer to read is bad practice.
  • ServerSocketChannel.accept() may return null.
  • Invalid code displaying a string after reading.
  • There is no need to use Map when keys have attachments.
  • There is no need to continue testing Thread.interrupted() when NIO is interrupted.
  • It is not necessary to close all that only one of the IOException on one channel.

Try to find something better.

+3
source

I believe that the ConnectException that you get with 500 threads does not come from SocketTest.connect() . This can come from any other input / output method.

To quickly fix (and convince yourself), you can explicitly catch a ConnectException in the main try-catch as follows:

 try { // connect, write, and read ... } catch (ConnectException ce) { // <-- catch the more specific Exception first System.out.println("You caught a ConnectException."); } catch (IOException e1) { // <-- you originally only caught this // TODO Auto-generated catch block e1.printStackTrace(); } finally { 

As for this, I can say that I am currently scaling up hundreds of threads to test the SOAP service. I also get dropped connections everywhere, so maybe this can be expected with so many parallel threads.

0
source

All Articles