JAVA:NIO

楚浩然
2023-12-01
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.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;

/**
 * desc:NIO的服务端实现
 *
 */

public class NIOServer {
    public static void main(String[] args) throws IOException {
        //创建服务端ServerSocketChannel实例
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        //绑定端口号
        serverSocketChannel.bind(new InetSocketAddress(6667));

        System.out.println("服务端启动。。。");
        //创建selector实例
        Selector selector = Selector.open();

        //将serverSocketChannel设置为非阻塞 false:设置为非阻塞 true:设置为阻塞
        serverSocketChannel.configureBlocking(false);

        //将serverSocketChannel注册到selector实例上,并对accept事件进行监听
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

        //选择器进行阻塞,直到有监听事件发生后才进行返回
        while (selector.select() > 0) {
            //对所有监听事件的集合进行遍历
            Iterator <SelectionKey> iterator = selector.selectedKeys().iterator();
            while (iterator.hasNext()) {
                SelectionKey key = iterator.next();
                iterator.remove();
                //处理的是accept事件
                if (key.isValid() && key.isAcceptable()) {
                    ServerSocketChannel ssc = (ServerSocketChannel) key.channel();
                    //接收新用户的连接,要进行IO操作
                    SocketChannel socketChannel = ssc.accept();
                    //将新用户连接设置为非阻塞事件
                    socketChannel.configureBlocking(false);
                    //将socketChannel注册到selector实例上
                    socketChannel.register(selector, SelectionKey.OP_READ);

                    key.cancel();
                }

                //处理读事件
                if (key.isValid() && key.isReadable()) {
                    SocketChannel socketChannel = (SocketChannel) key.channel();
                    //创建buff实例
                    ByteBuffer buffer = ByteBuffer.allocate(1024);
                    //将数据读取到buff实例中
                    socketChannel.read(buffer);
                    //反转
                    buffer.flip();
                    byte[] bytes = new byte[buffer.remaining()];
                    //将缓存数据读到byte中
                    buffer.get(bytes);

                    String msg = new String(bytes);
                    System.out.println("客户端发送消息:"+msg);
                    key.cancel();

                    //关闭用户连接
                    socketChannel.close();

                }
            }
        }

        System.out.println("服务端结束。。。");
        //关闭操作
        selector.close();
        serverSocketChannel.close();
    }
}
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;
import java.util.Iterator;
import java.util.Set;


public class NIOClient {
    public static void main(String[] args) throws IOException {
        //创建SocketChannel实例
        SocketChannel socketChannel = SocketChannel.open();

        //创建选择器实例
        Selector selector = Selector.open();

        //设置socketChannel非阻塞
        socketChannel.configureBlocking(false);

        //connect本身是阻塞的,将socketChannel设置为非阻塞,则该connect无论是否连接成功都要立即返回
        if (!socketChannel.connect(new InetSocketAddress("127.0.0.1",6667))){
            //当前连接服务端还未连接上则注册到选择器上进行监听
            //将socketChannel注册到selector上
            socketChannel.register(selector, SelectionKey.OP_CONNECT);
        }

        int num;
        while ( (num = selector.select(1000)) > 0) {
            System.out.println("select 返回:"+num);
            //获取注册到选择器上的事件
            Set <SelectionKey> selectionKeys = selector.selectedKeys();
            Iterator <SelectionKey> iterator = selectionKeys.iterator();

            while (iterator.hasNext()) {
                SelectionKey key = iterator.next();
                iterator.remove();

                //可连接事件完成
                if (key.isValid() && key.isConnectable()) {
                    SocketChannel channel = (SocketChannel) key.channel();
                    key.cancel();
                    if (!channel.finishConnect()) {
                        //连接为完成,则直接结束掉该用户连接
                        System.exit(1);
                    }

                    //连接完成
                    //创建发送内容的缓冲区
                    ByteBuffer buffer = ByteBuffer.allocate(1024);
                    buffer.put("Hello Word".getBytes());
                    buffer.flip();
                    //给服务端发送消息
                    socketChannel.write(buffer);
                    System.out.println("给服务端发送消息完成");
                }
            }
        }

        //关闭操作
        selector.close();
        socketChannel.close();

        System.out.println("客户端进行关闭操作");
    }
}

 

 类似资料:

相关阅读

相关文章

相关问答