由于功能太过简单,就不过多阐述了,直接上阻塞式代码:
package com.lql.nio; import org.junit.Test; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.nio.file.Paths; import java.nio.file.StandardOpenOption; /** * @author: lql * @date: 2019.11.01 * Description: 客户端发送一条数据给服务端,服务端接收后反馈一条信息 */ public class TestBlockingNIO2 { @Test public void client() { SocketChannel socketChannel = null; FileChannel inChannel = null; try { //获取通道 socketChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1", 8002)); inChannel = FileChannel.open(Paths.get("2.png"), StandardOpenOption.READ); //获取缓冲区 ByteBuffer byteBuffer = ByteBuffer.allocate(1024); while (inChannel.read(byteBuffer) != -1) { byteBuffer.flip(); socketChannel.write(byteBuffer); byteBuffer.clear(); } //切断 socketChannel.shutdownOutput(); //接收服务器端的反馈 int len = 0; while ((len = socketChannel.read(byteBuffer)) != -1) { byteBuffer.flip(); System.out.println(new String(byteBuffer.array(), 0, len)); byteBuffer.clear(); } } catch (IOException e) { e.printStackTrace(); } finally { if (inChannel != null) { try { inChannel.close(); } catch (IOException e) { e.printStackTrace(); } } if (socketChannel != null) { try { socketChannel.close(); } catch (IOException e) { e.printStackTrace(); } } } } @Test public void server() { ServerSocketChannel serverSocketChannel = null; FileChannel outChannel = null; try { serverSocketChannel = ServerSocketChannel.open(); outChannel = FileChannel.open(Paths.get("wy.png"), StandardOpenOption.WRITE, StandardOpenOption.CREATE); SocketChannel socketChannel = serverSocketChannel.bind(new InetSocketAddress("127.0.0.1", 8002)).accept(); ByteBuffer buffer = ByteBuffer.allocate(1024); while (socketChannel.read(buffer) != -1) { buffer.flip(); outChannel.write(buffer); buffer.clear(); } //接收完发送反馈给客户端 buffer.put("服务器端接收客户端数据成功!!!".getBytes()); buffer.flip(); socketChannel.write(buffer); } catch (IOException e) { e.printStackTrace(); } finally { if (outChannel != null) { try { outChannel.close(); } catch (IOException e) { e.printStackTrace(); } } if (serverSocketChannel != null) { try { serverSocketChannel.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
接来下是非阻塞式的代码:
package com.lql.nio; import org.junit.Test; 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.time.LocalDateTime; import java.util.Iterator; /** * @author: lql * @date: 2019.11.01 * Description: 非阻塞式(得有Channel,Buffer,Selector) */ public class TestNonBlockingNIO { //客户端 @Test public void client() { SocketChannel socketChannel = null; try { //获取通道 socketChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1", 8006)); //切换成非阻塞模式 socketChannel.configureBlocking(false); //获取缓冲区 ByteBuffer buf = ByteBuffer.allocate(1024); //发送数据给服务端 buf.put(LocalDateTime.now().toString().getBytes()); buf.flip(); socketChannel.write(buf); buf.clear(); } catch (IOException e) { e.printStackTrace(); } finally { if (socketChannel != null) { try { socketChannel.close(); } catch (IOException e) { e.printStackTrace(); } } } } @Test public void Server() { ServerSocketChannel serverSocketChannel = null; try { serverSocketChannel = ServerSocketChannel.open(); //切换非阻塞模式 serverSocketChannel.configureBlocking(false); //绑定并接收 serverSocketChannel.bind(new InetSocketAddress("127.0.0.1", 8006)); //获取选择器 Selector selector = Selector.open(); //将通道注册到选择器上,指定监听“接收”事件 serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); //轮询式的获取选择器上已经“准备就绪”的事件 while (selector.select() > 0) { //获取所有监听的事件 Iterator<SelectionKey> it = selector.selectedKeys().iterator(); while (it.hasNext()) { //获取准备就绪的事件 SelectionKey key = it.next(); //判断具体是什么事件准备就绪 if (key.isAcceptable()) { //获取客户端链接 SocketChannel socketChannel = serverSocketChannel.accept(); //客户端通道切换成非阻塞 socketChannel.configureBlocking(false); //将该通道注册要选择器上 socketChannel.register(selector, SelectionKey.OP_READ); } else if (key.isReadable()) { //获取读就绪状态的通道 SocketChannel socketChannel = (SocketChannel) key.channel(); //读取数据 ByteBuffer buffer = ByteBuffer.allocate(1024); int len = 0; while ((len = socketChannel.read(buffer)) != -1) { buffer.flip(); System.out.println(new String(buffer.array(), 0, len)); buffer.clear(); } } //取消选择键 it.remove(); } } } catch (IOException e) { e.printStackTrace(); } finally { } } }