我的简单Java NIO客户端-服务器非阻塞连接无法工作

我的简单Java NIO客户端-服务器非阻塞连接无法工作,java,nio,Java,Nio,我正在尝试使用一个简单的客户机-服务器程序,最终目标是实现双向通信。由于某种原因,当我只是实例化客户机类以使其连接到服务器而不发送任何数据时,它不起作用,并引发无法建立环回连接异常。当我通过stdin进行一个while循环读取时,它就工作了。我需要先建立连接,然后每隔一段时间向服务器发送一条消息。我怎样才能修好它 客户端代码: import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBu

我正在尝试使用一个简单的客户机-服务器程序,最终目标是实现双向通信。由于某种原因,当我只是实例化客户机类以使其连接到服务器而不发送任何数据时,它不起作用,并引发无法建立环回连接异常。当我通过stdin进行一个while循环读取时,它就工作了。我需要先建立连接,然后每隔一段时间向服务器发送一条消息。我怎样才能修好它

客户端代码:

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;

public class ClientCore {

    SelectionKey selkey;
    Selector sckt_manager ;
    SocketChannel sc;

    public ClientCore() {
        try {
            sc = SocketChannel.open();
            sc.configureBlocking(false);
            sc.connect(new InetSocketAddress(8888));

            // should not proceed until connect is finished
            while (!sc.finishConnect()) {
            }

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

    void send(String message) {
        try {
            if (!message.equalsIgnoreCase("end")) {
                System.out.println("Sending a request to the server ...");
                ByteBuffer buffer = ByteBuffer.wrap(message.getBytes());
                sc.write(buffer);
            }
        } catch (IOException e) {
        }

    }

    public static void main(String[] args) throws Exception {
        ClientCore cl = new ClientCore();
        cl.send("hello");
    }
}
服务器代码:

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.channels.WritableByteChannel;
import java.nio.channels.spi.SelectorProvider;

public class ServerCore extends Thread {

    SelectionKey selkey = null;
    Selector sckt_manager = null;

    public void run() {
        try {
            coreServer();
        } catch (Exception ej) {
            ej.printStackTrace();
        }
    }

    private void coreServer() {
        try {
            ServerSocketChannel ssc = ServerSocketChannel.open();
            try {
                ssc.socket().bind(new InetSocketAddress(8888));

                while (true) {

                    sckt_manager = SelectorProvider.provider().openSelector();
                    ssc.configureBlocking(false);
                    SocketChannel sc = ssc.accept();
                    register_server(ssc, SelectionKey.OP_ACCEPT);
                    if (sc == null) {
                    } else {

                        System.out
                                .println("Received an incoming connection from "
                                        + sc.socket().getRemoteSocketAddress());
                        printRequest(sc);
                        System.err.println("testing 1");
                        String HELLO_REPLY = "Sample Display";
                        ByteBuffer buffer = ByteBuffer.wrap(HELLO_REPLY .getBytes());
                        System.err.println("testing 2");
                        sc.write(buffer);
                        System.err.println("testing 3");
                        sc.close();
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (ssc != null) {
                    try {
                        ssc.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        } catch (Exception E) {
            System.out.println("Ex in servCORE   " + E);
        }
    }

    private static void printRequest(SocketChannel sc) throws IOException {

        ReadableByteChannel rbc = Channels.newChannel(sc.socket()
                .getInputStream());
        WritableByteChannel wbc = Channels.newChannel(System.out);
        ByteBuffer b = ByteBuffer.allocate(1024); // read 1024 bytes
        while (rbc.read(b) != -1) {
            b.flip();
            while (b.hasRemaining()) {
                wbc.write(b);
                System.out.println();
            }
            b.clear();
        }
    }

    public void register_server(ServerSocketChannel ssc, int selectionkey_ops)
            throws Exception {
        ssc.register(sckt_manager, selectionkey_ops);
    }

    public static void main(String[] args) {
        ServerCore st = new ServerCore();
        st.coreServer();
    }
}

这不是异步代码。它是非阻塞代码。您的连接代码完全等同于在设置非阻塞模式之前进行连接,只是后者不会占用CPU。您不需要每次在循环中都使用新的选择器,也不需要将ServerSocketChannel设置为非阻塞模式:而且由于您不使用选择器,因此很难理解为什么要使用选择器。这段代码没有多大意义。你学习过Oracle NIO教程吗?我遵循了Stackoverflow帖子中的一个示例代码:只要我们有一个从stdin读取的循环,它就可以工作,而当循环单独位于另一个函数中时,它就不工作了!如果我们要集中修改它,让我放另一个我尝试过的代码。我怎么能使它异步呢?我不知道你到底为什么要从问题中复制代码。你应该从答案中复制它。这是胡说八道,答案是在别处引用OP。我也只能这样做。您可以通过将其全部丢弃并使用AsynchronousSocketChannel和friends来实现异步,但为什么呢?您的实际目标是什么?“队列中的每一方轮询消息”正在忙着等待。你把四件不同的事情混为一谈:1忙着等待;2个阻塞I/O,3个非阻塞I/O;4异步I/O。除了可以通过1实现2之外,没有两个是相同的。