目录
一、非阻塞概述
- 一、非阻塞概述
- 二、非阻塞模式服务端代码示例(使用nio实现)
- 三、非阻塞模式客户端代码示例(使用nio实现)
- 四、工具类代码示例
- 五、非阻塞模式代码示例本地调试
- 非阻塞模式下,相关方法都会不会让线程暂停。 (1)、在 ServerSocketChannel.accept 在没有连接建立时,会返回 null,继续运行; (2)、SocketChannel.read 在没有数据可读时,会返回 0,但线程不必阻塞,可以去执行其它 SocketChannel 的 read 或是去执行 ServerSocketChannel.accept; (3)、写数据时,线程只是等待数据写入 Channel 即可,无需等 Channel 通过网络把数据发送出去;
- 非阻塞模式下,即使没有连接建立和可读数据,线程仍然在不断运行,白白浪费了 cpu。
- 数据复制过程中,线程实际还是阻塞的(AIO 改进的地方)。
-
服务端代码
package com.example.nettytest.nio.day3; import lombok.extern.slf4j.Slf4j; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.*; import java.util.ArrayList; import java.util.Iterator; import static com.example.nettytest.nio.day1.ByteBufferUtil.debugRead; /** * @description: 非阻塞模式服务端代码示例(使用nio实现) * @author: xz * @create: 2022-08-16 21:21 */ @Slf4j public class TestServer { public static void main(String[] args) throws IOException { nioNoBlockServer(); } /** * 使用nio来理解非阻塞模式(单线程服务端) * */ private static void nioNoBlockServer() throws IOException { //1、创建ByteBuffer,容量16 ByteBuffer byteBuffer = ByteBuffer.allocate(16); //2、创建服务器 ServerSocketChannel ssc = ServerSocketChannel.open(); ssc.configureBlocking(false);//ssc设置为非阻塞模式 //3、绑定监听端口 ssc.bind(new InetSocketAddress(8080)); //4、连接集合 ArrayList channels = new ArrayList(); while(true){ //5、accept() 建立与客户端连接, SocketChannel 用来与客户端之间通信 SocketChannel sc = ssc.accept();//启动服务端,非阻塞方法,线程会继续运行。如果没有建立连接 sc=null if(sc !=null){ log.info("create connected SocketChannel... {}", sc); sc.configureBlocking(false);//sc设置为非阻塞模式 //6、建立的客户端连接sc 添加到 连接集合channels中 channels.add(sc); } //7、遍历连接集合 for(SocketChannel channel : channels){ // 8、 接收客户端发送的数据,从channel中读取数据写入到byteBuffer中 int read = channel.read(byteBuffer);// 启动客户端,非阻塞方法,线程会继续运行,read 返回 0 if(read>0){ //切换读模式 byteBuffer.flip(); //打印可读取内容(从byteBuffer中读取数据内容) debugRead(byteBuffer); //切换回写模式 byteBuffer.clear(); log.info("after read channel ... {}", channel); } } } } }
-
客户端代码
package com.example.nettytest.nio.day3; import java.io.IOException; import java.net.InetSocketAddress; import java.net.SocketAddress; import java.nio.channels.SocketChannel; /** * @description: * @author: xz * @create: 2022-08-16 21:45 */ public class TestClient { public static void main(String[] args) throws IOException { SocketChannel sc = SocketChannel.open(); sc.connect(new InetSocketAddress("localhost", 8080)); SocketAddress address = sc.getLocalAddress(); //debug模式后,点击src参数,右键选择 输入表达式sc.write(Charset.defaultCharset().encode("hello"));然后执行 System.out.println("waiting..."); } }
-
工具类,打印输入、输出数据使用
package com.example.nettytest.nio.day1; import io.netty.util.internal.StringUtil; import java.nio.ByteBuffer; import static io.netty.util.internal.MathUtil.isOutOfBounds; import static io.netty.util.internal.StringUtil.NEWLINE; public class ByteBufferUtil { private static final char[] BYTE2CHAR = new char[256]; private static final char[] HEXDUMP_TABLE = new char[256 * 4]; private static final String[] HEXPADDING = new String[16]; private static final String[] HEXDUMP_ROWPREFIXES = new String[65536 >>> 4]; private static final String[] BYTE2HEX = new String[256]; private static final String[] BYTEPADDING = new String[16]; static { final char[] DIGITS = "0123456789abcdef".toCharArray(); for (int i = 0; i 4 & 0x0F]; HEXDUMP_TABLE[(i
关注打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?