NIO客户端发出异常:java.net.ConnectException:连接被拒绝:无进一步信息

NIO客户端发出异常:java.net.ConnectException:连接被拒绝:无进一步信息,java,nio,Java,Nio,我修改了可用的示例代码 我的客户: 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 Thr

我修改了可用的示例代码 我的客户:

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);
    }
}
公共类客户端{
公共静态void main(字符串[]args){
int n=10000;
SocketTest[]st=新SocketTest[n];

对于(int i=0;i我相信您使用500个线程获得的
ConnectException
不是来自
SocketTest.connect()
。它可能来自任何其他IO方法

为了快速修复(并说服自己),您可以在主
try catch
块中显式捕获
ConnectException
,如下所示:

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 {
试试看{
//连接、写入和读取。。。

}捕获(连接异常){/
连接异常:拒绝连接
意味着在您尝试连接的IP:端口或服务器的侦听积压队列填满的某些平台上没有侦听任何内容。如果抛出了它,并且您正确捕获了它,您肯定会捕获它。您必须详细介绍实际发生的情况以及实际捕获的内容ode看起来需要进一步的帮助

但是,您还有许多其他问题:

private void connect(SelectionKey key) throws IOException {
    SocketChannel channel = (SocketChannel) key.channel();
    try
    {
        if(!channel.finishConnect())
            System.out.println("* Here *");
此时,如果
finishConnect()
返回false,则应返回。您不应中断并重新注册
OP\u WRITE的通道。
连接仍处于挂起状态。打印
“*此处*”
也很无效。请尝试打印一些有意义的内容

    }
    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);
另一种方法是
key.interesttops(SelectionKey.OP_WRITE);

沉睡在网络代码中简直是浪费时间。它解决不了任何问题

您假设
write()
完全成功,并且忽略它返回的计数

您使用的参考资料质量相当差:

  • 关于
    write()
    的注释与上述相同
  • flip()
  • 取消键将关闭通道
  • 您不必清除全新的
    ByteBuffer,
    ,但在任何情况下,为每次读取分配
    ByteBuffer
    都是不好的做法
  • ServerSocketChannel.accept()
    可以返回
    null。
  • 读取后显示字符串的代码不正确
  • 当键具有附件时,无需使用
    映射
  • 不管怎样,当NIO是可中断的时,没有必要继续测试
    Thread.interrupted()
  • 没有必要因为一个频道上的一个
    IOException
    而关闭所有内容

尝试找到更好的方法。

尝试使用命令执行Telnet-

telnet [host IP] [port] 

问题可能是防火墙阻止端口。

您使用的是windows还是linux?感谢您的解释。服务器肯定已启动并正在侦听。我不知道侦听队列如何填满。请参阅我的编辑。如果您的服务器不以最快的速度接受连接,侦听队列可能会填满。这听起来像是问题:何时Windows待办事项队列已满,但开始拒绝连接。1)你能告诉我积压工作队列最常见的大小是什么吗?我读到非服务器Windows机器的是5,服务器机器的是200。我对吗?2)我在创建新客户端时设置了线程睡眠,即100个客户端,然后5秒睡眠,然后是100个客户端。这对大约4000个线程有效。但当我创建10000个线程时,大约有8500个线程存活下来。For rest连接被拒绝。您能告诉我原因是什么吗?我认为积压队列不能作为最初处理它们的原因?@cruxioneffux(1)50或系统默认值。(2)当您将睡眠放入时,积压队列不会比接受循环提前太多。当您将它们取出时,接受循环无法跟上,因此积压队列已满。查看是否可以加快接受循环:例如,将线程初始化移动到
run()中
method。它将来自
SocketChannel.finishConnect()。