1 基本介绍

通常来说NIO中的所有IO都是从 Channel(通道) 开始的。NIO 的通道类似于流,但有些区别如下:

1. 通道可以读也可以写,流一般来说是单向的(只能读或者写,所以之前我们用流进行IO操作的时候需要分别创建一个输入流和一个输出流)

2. 通道可以异步读写

3. 通道总是基于缓冲区Buffer来读写

image.png

2 Channel常用类介绍

  1. Channel接口常 用 的Channel实现类类 有 :FileChannel , DatagramChannel ,ServerSocketChannel和SocketChannel 。FileChannel 用于文件的数据读写, DatagramChannel 用于 UDP 的数据读写, ServerSocketChannel 和SocketChannel 用于 TCP 的数据读写。【ServerSocketChanne类似 ServerSocket , SocketChannel 类似 Socket】

  2. SocketChannel 与ServerSocketChannel    类似 Socke和ServerSocket,可以完成客户端与服务端数据的通信工作.


image.png



3 ServerSocketChannel

服务端实现步骤:

1. 打开一个服务端通道

2. 绑定对应的端口号

3. 通道默认是阻塞的,需要设置为非阻塞

4. 检查是否有客户端连接 有客户端连接会返回对应的通道

5. 获取客户端传递过来的数据,并把数据放在byteBuffer这个缓冲区中

6. 给客户端回写数据

7. 释放资源

代码实现:

package com.test.channel;

import java.io.IOException;

import java.net.InetSocketAddress;

import java.nio.ByteBuffer;

import java.nio.channels.ServerSocketChannel;

import java.nio.channels.SocketChannel;

import java.nio.charset.StandardCharsets;

/**

* 服务端

*/

public class NIOServer {

  public static void main(String[] args) throws IOException,

InterruptedException {

    //1. 打开一个服务端通道

    ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();

    //2. 绑定对应的端口号

    serverSocketChannel.bind(new InetSocketAddress(9999));

    //3. 通道默认是阻塞的,需要设置为非阻塞

    // true 为通道阻塞 false 为非阻塞

    serverSocketChannel.configureBlocking(false);

    System.out.println("服务端启动成功..........");

    while (true) {

      //4. 检查是否有客户端连接 有客户端连接会返回对应的通道 , 否则返回null

      SocketChannel socketChannel = serverSocketChannel.accept();

      if (socketChannel == null) {

        System.out.println("没有客户端连接...我去做别的事情");

        Thread.sleep(2000);

        continue;

     }

      //5. 获取客户端传递过来的数据,并把数据放在byteBuffer这个缓冲区中

      ByteBuffer byteBuffer = ByteBuffer.allocate(1024);

      //返回值:

      //正数: 表示本次读到的有效字节个数.

      //0  : 表示本次没有读到有效字节.

      //-1 : 表示读到了末尾

      int read = socketChannel.read(byteBuffer);

      System.out.println("客户端消息:" +

          new String(byteBuffer.array(), 0, read,

StandardCharsets.UTF_8));

      //6. 给客户端回写数据

      socketChannel.write(ByteBuffer.wrap("没

钱".getBytes(StandardCharsets.UTF_8)));

      //7. 释放资源

      socketChannel.close();

   }

 }

}

4 SocketChannel

实现步骤

1. 打开通道

2. 设置连接IP和端口号

3. 写出数据

4. 读取服务器写回的数据

5. 释放资源

代码实现:

package com.test.channel;

import java.io.IOException;

import java.net.InetSocketAddress;

import java.nio.ByteBuffer;

import java.nio.channels.SocketChannel;

import java.nio.charset.StandardCharsets;

/**

* 客户端

*/

public class NIOClient {

  public static void main(String[] args) throws IOException {

    //1.打开通道

    SocketChannel socketChannel = SocketChannel.open();

    //2.设置连接IP和端口号

    socketChannel.connect(new InetSocketAddress("127.0.0.1", 9999));

    //3.写出数据

    socketChannel.write(ByteBuffer.wrap("老板, 该还钱

拉!".getBytes(StandardCharsets.UTF_8)));

    //4.读取服务器写回的数据

    ByteBuffer readBuffer = ByteBuffer.allocate(1024);

    int read=socketChannel.read(readBuffer);

    System.out.println("服务端消息:" + new String(readBuffer.array(), 0, read,

StandardCharsets.UTF_8));

    //5.释放资源

    socketChannel.close();

 }

}

结束。。。