NIO客户端给出异常:java.net.ConnectException:连接被拒绝:没有更多信息

问题描述 投票:5回答:3

我修改了可用的示例代码here for Client and Server我的客户:

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

我通过创建多个线程在同一台计算机上创建多个客户端。线程数由n的值确定。当我运行很少的客户端时,我没有遇到任何问题,但是当我使用500的n(即500个客户端线程)运行时,某些线程可以正确运行,但是在某些情况下我会遇到以下问题: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)

第143行是:if(!channel.finishConnect())因此,当我阅读此方法的文档时,它会抛出:

NoConnectionPendingException-如果未连接此通道并且尚未启动连接操作。

ClosedChannelException-如果此通道已关闭。

AsynchronousCloseException-如果在进行连接操作时另一个线程关闭了此通道。

ClosedByInterruptException-如果在进行连接操作时另一个线程中断了当前线程,从而关闭了通道并设置了当前线程的中断状态。

IOException

-如果发生其他一些I / O错误。

但是例外是ConnectException。我尝试捕获它,但是它没有进入捕获块。

任何帮助将不胜感激。谢谢。编辑:

我正在窗户上工作。我尝试更改n的值,以查看创建了多少个客户端以及导致了多少个异常,这些都是结果(我知道在每个测试之后等待更多的时间将允许更多的开放套接字,就像在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 我对只有这么多的客户端才能建立连接感到困扰。任何人都可以建议更好的参考来阅读Client Server NIO。

编辑2

正如EJP在其评论中提到的,“ Backlog Queue”窗口已满。我修改了客户端代码以生成100个线程,然后休眠5秒钟,这样队列上的负载就不大了,并且大多数连接都成功了(但是,当建立10,000个连接时,仍然有些失败了。)

我修改了此处可用于客户端和服务器的示例代码。我的客户端:公共类Client {public static void main(String [] args){int n = 10000; SocketTest [] st =新的SocketTest [n]; ...

java nio
3个回答
5
投票

ConnectException: connection refused表示没有任何内容在您尝试连接的IP:端口上侦听,或在服务器的侦听积压队列已满的某些平台上侦听。如果将其抛出并正确捕获,则肯定会捕获。您需要扩展实际发生的情况以及实际捕获代码的外观,以获取进一步的帮助。


1
投票

我相信您拥有500个线程的ConnectException不是来自SocketTest.connect()。它可能来自其他任何IO方法。


0
投票

尝试使用命令进行Telnet-

© www.soinside.com 2019 - 2024. All rights reserved.