java.net.ConnectException:连接超时:没有进一步的信息

时间:2015-06-05 14:57:15

标签: java nio

今天我在不同的机器上测试服务器和客户端代码。 两者都在同一个Wi-Fi网络上。

我使用下面的代码创建了客户端,并为许多线程获得了这个例外:

java.net.ConnectException: Connection timed out: no further information at sun.nio.ch.SocketChannelImpl.checkConnect(Native Method) at sun.nio.ch.SocketChannelImpl.finishConnect(Unknown Source) at SocketTest.connect(Client.java:188) at SocketTest.run(Client.java:73) at java.lang.Thread.run(Unknown Source)

第73行是connect(key) 第188行是if(!(channel.finishConnect()))

所以客户端线程无法连接,因为服务器没有回复?对吗?

问题)当我在同一台机器localhost上运行Server和Client时,不会出现此异常。可能是什么原因? (网络问题?)。

此外,我还将public void bind(SocketAddress endpoint,int backlog)中的Backlog队列参数用作2000.虽然确切的大小未知(大约200?)但我使用的是一个较大的值,因此将使用最大值。(对吗?还是Java会排队?)。

这可能是一个原因:服务器将请求放在积压队列中,直到它有时间为它服务,超时可能发生在客户端?

客户:

public class Client {

public static void main(String[] args) {

    int n=100;
    SocketTest [] st= new SocketTest[n];
    for(int i=0;i<n;i++)
        st[i]= new SocketTest("hi");


    for(int i=0;i<n;i++)
    {
        if(i%50 == 0)
        try{
            Thread.sleep(5000);
        }
        catch(InterruptedException ie)
        {
            System.out.println(""+ie);
        }
        new Thread(st[i]).start();

    }
}
}
class SocketTest implements Runnable {

    private String message = "";
    ByteBuffer readBuffer = ByteBuffer.allocate(1000);
    private Selector selector;
    private int i;
    public static AtomicInteger cnt= new AtomicInteger(0);

    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("192.168.1.10", 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(ClosedByInterruptException e)
        {
            // let go of thread
        }
        catch(CancelledKeyException e){

            e.printStackTrace();
        }
        catch (IOException e1) {
            System.out.println("IOE Occured|maybe Server died");
            e1.printStackTrace();
        } finally {
            close();
        }
    }

    private void close(){

        try {
                if(selector!=null)
                    selector.close();
            }
            catch(Exception e) 
            {
                    e.printStackTrace();
            }

    }

    private void read (SelectionKey key) throws IOException {
        SocketChannel channel = (SocketChannel) key.channel();

        readBuffer.clear();
        int length;
        try{
        length = channel.read(readBuffer);

        } catch (IOException e){
            System.out.println("Reading problem, closing connection for  : "+channel.getLocalAddress());
            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;
        if(i==2)
        {
            cnt.addAndGet(1);
            System.out.println("****"+cnt.get()+"****");
        }

        try{
            Thread.sleep(5000);
        }
        catch(InterruptedException ie)
        {
            System.out.println(""+ie);
            //Thread.currentThread().interrupt();
        }

        //assuming all goes in one shot
        channel.write(ByteBuffer.wrap(message.getBytes()));

        key.interestOps(SelectionKey.OP_READ/*|SelectionKey.OP_WRITE*/);
    }

    private void connect(SelectionKey key){
        SocketChannel channel= (SocketChannel) key.channel();

        try
        {
            if(!(channel.finishConnect())){
                //System.out.println("* Here *");
                return;
            }
        }
        catch(ConnectException e){
            System.out.println("Conect Exception");
            e.printStackTrace();
            try{channel.close();}
            catch(IOException ie){ie.printStackTrace();key.cancel();return;}
            return;
        }
        catch(IOException e)
        {
            System.out.println("BP 1"+e);
            e.printStackTrace();
            try{channel.close();}
            catch(IOException ie){ie.printStackTrace();key.cancel();return;}
            return;
        }
            //channel.configureBlocking(false);
            //channel.register(selector, SelectionKey.OP_WRITE);
        key.interestOps(SelectionKey.OP_WRITE);

    }
}

1 个答案:

答案 0 :(得分:0)

连接超时,因为服务器没有回复。

  

当我在同一台机器localhost上运行Server和Client时,不会出现此异常。可能是什么原因? (网络问题?)。

为什么应该出现?服务器在那里,客户端在那里,中间没有网络问题。这个问题没有意义。

  

此外,我还将public void bind(SocketAddress endpoint,int backlog)中的Backlog队列参数用作2000.虽然确切的大小未知(大约200?)但我使用的是一个较大的值,因此将使用最大值。正确?

右。

  

或Java会排队吗?

我不知道这意味着什么。 Java没有对backlog参数做任何事情。它直接转向TCP。

  

这可能是一个原因:服务器将请求放在积压队列中,直到它有时间为它服务,超时可能发生在客户端?

没有。只有已完成的连接才会进入积压队列。