NIO实现通信聊天:
服务端步骤:
1.创建NI0通道,并且绑定端口
2.开启非阻塞模式
3.创建Selector选择器,并将通道注册到选择器上边,设置关系事件---》新链接
4.循环监听通道的事件
5.监听到新连接事件
5.1:建立和客户端连接的通道
5.2:通道设置为非阻塞
5.3:通道设置完成,将关系事件设置为读取
6.监听到读取事件
6.1:获取客户端通道
6.2:将通道的数据写入到缓冲区(buffer)当中
6.3:打印数据
服务器端:
- public class Server {
- public static void main(String[] args) throws IOException {
- // 获取一个ServerSocket通道
- ServerSocketChannel serverChannel = ServerSocketChannel.open();
- // serverChannel通道一直监听4700端口
- serverChannel.socket().bind(new InetSocketAddress(4700));
- // 设置serverChannel为非阻塞
- serverChannel.configureBlocking(false);
- //创建Selector选择器用来监听通道
- Selector selector = Selector.open();
- // 把ServerSocketChannel注册到selector中,并且selector对客户端的连接操作感兴趣
- serverChannel.register(selector, SelectionKey.OP_ACCEPT);
- System.out.println("服务启动成功!");
-
- while (true) {
- /*
- * 如果事件没有到达 selector.select() 会一直阻塞等待
- */
- selector.select();
- Set
selectionKeys = selector.selectedKeys(); - Iterator
iterator = selectionKeys.iterator(); - while (iterator.hasNext()) {
- SelectionKey key = iterator.next();
- if (key.isAcceptable()) // 如果是OP_ACCEPT事件,则进行连接获取和事件注册
- {
- ServerSocketChannel server = (ServerSocketChannel) key.channel(); //连接获取
- SocketChannel socketChannel = server.accept(); // 获取通道
- socketChannel.configureBlocking(false); // 设置为非阻塞
- socketChannel.register(selector, SelectionKey.OP_READ); //这里只注册了读事件,如果需要给客户端写数据,则需要注册写事件
- System.out.println("客户端连接成功!");
- } else if (key.isReadable()) //如果是OP_READ事件,则进行读取和打印
- {
- SocketChannel socketChannel = (SocketChannel) key.channel();
- ByteBuffer byteBuffer = ByteBuffer.allocate(128);//创建Buffer
- int len = socketChannel.read(byteBuffer);
- if (len > 0) //如果有数据,则打印数据
- {
- System.out.println("接受到客户端数据" + new String(byteBuffer.array()));
- }
- }
- // 从事件集合中删除本次处理的key,防止下次select重复处理
- iterator.remove();
-
- }
- }
- }
- }
客户端:
- public class Client {
- public static void main(String[] args) throws IOException {
- //打开channel通道
- SocketChannel socketChannel = SocketChannel.open();
- socketChannel.configureBlocking(false); //设置为非阻塞
- InetSocketAddress address = new InetSocketAddress("101.43.152.120",4700);
- while (!socketChannel.connect(address)){
- while (!socketChannel.finishConnect()){
- System.out.println("连接中,客户端可以进行其他工作");
- }
- // Scanner scanner = new Scanner(System.in);
- // String str = scanner.next();
- Scanner scanner=new Scanner(System.in);
- do {
- String str=scanner.next();
- ByteBuffer aa = ByteBuffer.wrap(str.getBytes()); // 将数据转换成字节信息写入到Buffer当中
- socketChannel.write(aa); //将Buffer当中的数据写入channel
- } while (!scanner.equals("bye"));
- scanner.close();
-
- System.in.read();
- }
- }
- }