有什么方法可以将数据作为响应从nio服务器发送到io客户端?

时间:2015-01-14 19:01:53

标签: java nio server

我可以从io客户端发送数据(仅使用套接字而不是套接字通道),但无法从nio服务器发送数据(使用套接字通道)。有什么问题?

通过I / O流和bytebuffer进行读/写的方式有区别吗?

public class Server {

    // this is equivalent to the server socket in the non nio world
    ServerSocketChannel serverSocketChannel;

    // this is the multiplexer which multiplexes the messages received from
    // different clients
    Selector selector;

    public Server() {
        try {

            // get a selector
            selector = Selector.open();

            // get a server socket channel
            serverSocketChannel = ServerSocketChannel.open();

            // we force the socket to be Non-blocking.
            // if it is set to "true" then this socket acts as a normal
            // (blocking) server socket
            serverSocketChannel.configureBlocking(false);

            // port and ip address where the server listens for connections
            InetSocketAddress add = new InetSocketAddress(
                InetAddress.getLocalHost(), 9999);

            // bind the server socket to the ip/port
            serverSocketChannel.socket().bind(add);

            // register the serverSocketChannel (for incoming connection events)
            // to the selector.
            // The "SelectionKey.OP_ACCEPT" parameter tells the selector that
            // this serverSocketChannel registers
            // itself for incoming (acceptable) connections
            SelectionKey key = serverSocketChannel.register(selector,
                SelectionKey.OP_ACCEPT);
            System.out.println("serverSocketChannel's registered key is : "
                + key.channel().toString());

            System.out.println();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        Server server = new Server();
        server.startListening();
    }

    private void startListening() {

        System.out.println("Server is listening on: "
            + serverSocketChannel.socket().getInetAddress()
                .getHostAddress() + ":"
            + serverSocketChannel.socket().getLocalPort());

        while (true) {
            try {

                // this line blocks until some events has occurred in the
                // underlying socket
                selector.select();

                // get the selected keys set
                Set selectedKeys = selector.selectedKeys();

                Iterator iterator = selectedKeys.iterator();

                while (iterator.hasNext()) {

                    SelectionKey key = (SelectionKey) iterator.next();

                    iterator.remove();

                    // a client has asked for a new connection
                    if (key.isAcceptable()) {
                        // only ServerSocketsChannels registered for OP_ACCEPT
                        // are excepted to receive an
                        // "acceptable" key

                        System.out.println("Key ready to perform accept() : "
                            + key.channel().toString());

                        // as usual the accept returns the plain socket towards
                        // the client
                        SocketChannel client = serverSocketChannel.accept();

                        // set the client socket to be non blocking
                        client.configureBlocking(false);

                        // register the client socket with the same selector to
                        // which we have registered the
                        // serverSocketChannel
                        client.register(selector, SelectionKey.OP_READ);
                        // client.register(selector, SelectionKey.OP_WRITE);
                        continue;
                    }

                    // the client has sent something to be read by this server
                    if (key.isReadable()) {

                        System.out.println("Key ready to perform read() : "
                            + key.channel().toString());

                        // get the underlying socket
                        SocketChannel client = (SocketChannel) key.channel();
                        ByteBuffer bb = ByteBuffer.allocate(10000);

                        // read the msg sent by the client
                        client.read(bb);

                        // display the message
                        bb.flip();
                        byte[] array = new byte[bb.limit()];
                        bb.get(array);
                        System.out.println(new String(array));

                        // send the message

                        ByteBuffer bb1 = ByteBuffer.allocate(10000);

                        String s = "server data";
                        byte[] array1 = new byte[bb1.limit()];
                        array1 = s.getBytes();
                        bb1.put(array1);
                        client.write(bb1);

                    }

                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    void write() {

    }


}

public class Client {
    static String IP = "192.168.123.105"; // server IP address
    public static void main(String[] args) throws UnknownHostException,
        IOException {
        // TODO Auto-generated method stub

        String msg;
        Socket socket = new Socket(IP, 9999);

        System.out.println("client: complete making socket");
        Scanner scan = new Scanner(System.in);
        System.out.println("client: input data to send");

        while (true) {
            // read
            System.out.print(">>>");
            msg = scan.nextLine();

            OutputStream out = socket.getOutputStream();
            DataOutputStream dou = new DataOutputStream(out);
            dou.writeUTF(msg);

            // write from server

            InputStream in = socket.getInputStream();
            DataInputStream din = new DataInputStream(in);
            String remsg = din.readUTF();
            System.out.println("client: data from server" + remsg);

            if (remsg.equalsIgnoreCase("END")) {
                System.out.println("SOCKET END");
                socket.close();
                break;

            }
        }
    }
}

1 个答案:

答案 0 :(得分:-1)

我解决了问题!

这是关于如何从客户端

中读取输入流的问题

我更改了部分客户端代码

  InputStream in = socket.getInputStream();
        DataInputStream din = new DataInputStream(in);
        String remsg = din.readUTF();
        System.out.println("client: data from server" + remsg);

ByteBuffer bb1 = ByteBuffer.allocate(10000);
            byte[] array1 = new byte[bb1.limit()];
            InputStream in = socket.getInputStream();
            in.read(array1);
            String remsg=new String(array1);

并在服务器代码中添加了OP_WRITE / isWritable(),如下所示

if (key.isReadable()) {

                    System.out.println("Key ready to perform read() : "
                            + key.channel().toString());

                    // get the underlying socket
                    SocketChannel client = (SocketChannel) key.channel();
                    ByteBuffer bb = ByteBuffer.allocate(1024);

                    // read the msg sent by the client
                    client.read(bb);

                    // display the message
                    bb.flip();
                    byte[] array = new byte[bb.limit()];
                    bb.get(array);
                    System.out.println(new String(array));

                    client.register(selector, SelectionKey.OP_WRITE);


                    continue;
                }



 if(key.isWritable()){

                    SocketChannel client = (SocketChannel) key.channel();
                      ByteBuffer bb1 = ByteBuffer.allocate(10000);

                        String s = "server data";
                        byte[] array1 = new byte[bb1.limit()];
                        array1 = s.getBytes();
                        bb1.put(array1);
                        bb1.flip();
                        client.write(bb1);
                    }