首页 > 解决方案 > Java SocketChannel 无法向 ServerSocketChannel 发送数据

问题描述

我正在尝试使用 NIO 和选择器在 Java 中编写一个简单的客户端/服务器。服务器非常简单,它是您随处可以找到的最典型的实现。下面是服务器的代码(看start()方法):

public final class MyServer {

    private int port;

    private String address;

    public MyServer(String address, int port) {
        this.address = address;
        this.port = port;
    }

    public void start() throws IOException {

        try {

            Selector selector = Selector.open();    

            ServerSocketChannel socket = ServerSocketChannel.open();
            InetSocketAddress addr = new InetSocketAddress(address, port);

            socket.bind(addr);
            socket.configureBlocking(false);

            boolean isAlive = true;
            SelectionKey selectKy = socket.register(selector, SelectionKey.OP_ACCEPT, null);

            while (isAlive) {

                selector.select();

                Set<SelectionKey> keysList = selector.selectedKeys();
                Iterator<SelectionKey> keys = keysList.iterator();

                while (keys.hasNext()) {
                    SelectionKey theKey = keys.next();

                    if (theKey.isAcceptable()) {

                        SocketChannel clientSocket = socket.accept();
                        clientSocket.configureBlocking(false);
                        clientSocket.register(selector, SelectionKey.OP_READ);

                    }

                    if (theKey.isReadable()) {

                        SocketChannel clientSocket = (SocketChannel) theKey.channel();
                        ByteBuffer buffer = ByteBuffer.allocate(9000);
                        clientSocket.read(buffer);

                        String result = new String(buffer.array()).trim();
                        System.out.println(" > SERVER: Request from " + clientSocket.getLocalAddress() + " [ toValidate = " + result + " ], sending tokens...");

                        //Now I send to the client a list
                        buffer.flip();

                        for (int i = 0; i < 5; ++i)
                            buffer.put((byte) getRandom(1, 10));

                        clientSocket.write(buffer);
                        buffer.clear();

                        System.out.println(" > SERVER: Response successfully sent");
                    }

                    keys.remove();
                }
            }

        } catch (Exception e) {
            System.out.println("[ SERVER ALERT: " + e.getMessage() + " ]");
        }

    }
}

如您所见,代码非常基本。在内部,if (theKey.isReadable())我尝试从客户端读取一个小字符串,将其打印到控制台,然后翻转缓冲区并将一些数据发送回客户端。


在这里,我们的客户很遗憾地遇到了我找不到的问题:

public void something() throws IOException, InterruptedException {

        ByteBuffer buffer = ByteBuffer.allocate(9000);

        //Note that mRequests is a List of strings
        try (SocketChannel client = SocketChannel.open(new InetSocketAddress(authIPAddr, authPort));) {
            //For each transaction in mRequests, get the tokens from the server and verify them
            for (String s : mRequests) {

                //Write the string to the buffer and send the string
                buffer.put(s.getBytes());
                client.write(buffer);

                buffer.rewind();

                //Get response from the server
                client.read(buffer);
                buffer.clear();      

                Thread.sleep(1000);
            }
        }

    }

问题正是在这里:

buffer.put(s.getBytes());
client.write(buffer);

buffer.rewind();

我可以说问题存在,因为服务器应该打印

服务器:来自 /127.0.0.1:2323 [ toValidate = {some_value} ] 的请求,发送令牌...

但它会打印

服务器:来自 /127.0.0.1:2323 [ toValidate = ] 的请求,发送令牌...

从这里我猜数据没有发送到服务器。我该如何解决这个问题?

标签: javasocketchannel

解决方案


推荐阅读