一、普通IO

传统的IO当客户端请求服务端的资源,这个时候不确定是否准备好资源。如果这个时候存在问题,当前线程则会一直等待,不能再处理其他问题。就造成了阻塞。

二、NIO

NIO新增了选择器,所有的通道都会注册到选择器上,由选择器进行监控。当选择器监控到,客户端请求的资源都准备好的时候,再调用服务端的一个或多个线程,从而提高线程的利用率。

阻塞式:

package com.stu.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;/*** 一、使用 NIO 完成王阔通信的三个核心:* 1. 通道(Channel):负责连接*  java.nio.channels.Channel 接口:*      |-- SelectableChannel:*          |-- SocketChannel:*          |-- ServerSocketChannel*          |-- DatagramChannel**          |-- Pipe.SinkChannel*          |-- Pipo.SourceChannel** 2. 缓冲区(Buffer):负责数据的存取* 3. 选择器(Selector): 是SelectableChannel的多路复用器。用于监控SelectableChannel 的IO 状况。**/
public class TestBlockingNIO {/*** 客户端*/@Testpublic void test1 () throws IOException {// 1. 获取通道SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1", 9998));FileChannel inChannel = FileChannel.open(Paths.get("1.jpeg"), StandardOpenOption.READ);// 2. 分配指定大小的缓冲区ByteBuffer byteBuffer = ByteBuffer.allocate(1024);// 3. 读取本地文件,并发送到服务器端while (inChannel.read(byteBuffer) != -1) {byteBuffer.flip();socketChannel.write(byteBuffer);byteBuffer.clear();}// 4. 关闭通道inChannel.close();socketChannel.close();}/*** 服务端*/@Testpublic void test2() throws IOException {// 1. 获取通道ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();FileChannel outFileChannel = FileChannel.open(Paths.get("3.jpg"), StandardOpenOption.WRITE,StandardOpenOption.CREATE, StandardOpenOption.READ);// 2. 绑定连接serverSocketChannel.bind(new InetSocketAddress(9998));// 3. 获取客户端连接的通道SocketChannel socketChannel = serverSocketChannel.accept();// 4. 分配指定大小的缓存区ByteBuffer byteBuffer = ByteBuffer.allocate(1024);// 5. 接收客户端的数据,并保存到本地while (socketChannel.read(byteBuffer) != -1) {byteBuffer.flip();outFileChannel.write(byteBuffer);byteBuffer.clear();}// 6. 关闭对应的通道socketChannel.close();outFileChannel.close();serverSocketChannel.close();}
}
package com.stu.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;public class TestBlockingNIO2 {/*** 客户端*/@Testpublic void client() throws IOException {SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1",9998));FileChannel inFileChannel = FileChannel.open(Paths.get("1.jpeg"), StandardOpenOption.READ);ByteBuffer byteBuffer = ByteBuffer.allocate(1024);while (inFileChannel.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();}inFileChannel.close();socketChannel.close();}/*** 服务端*/@Testpublic void server() throws IOException {ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();FileChannel outFileChannel = FileChannel.open(Paths.get("5.jpg"), StandardOpenOption.WRITE,StandardOpenOption.CREATE);serverSocketChannel.bind(new InetSocketAddress(9998));SocketChannel socketChannel = serverSocketChannel.accept();ByteBuffer byteBuffer = ByteBuffer.allocate(1024);while (socketChannel.read(byteBuffer) != -1) {byteBuffer.flip();outFileChannel.write(byteBuffer);byteBuffer.clear();}// 发送反馈给客户端byteBuffer.put("服务端接收客户端数据成功".getBytes());byteBuffer.flip();socketChannel.write(byteBuffer);socketChannel.close();outFileChannel.close();serverSocketChannel.close();}
}

SelectionKey:

非阻塞式:

package com.stu.nio;import org.junit.Test;import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Date;
import java.util.Iterator;
import java.util.Scanner;public class TestNonBlockingNIO {/*** 客户端*/@Testpublic void client() throws IOException {// 1.获取通道SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1", 9998));// 2.切换非阻塞模式socketChannel.configureBlocking(false);// 3. 分配指定大小的缓存区ByteBuffer byteBuffer = ByteBuffer.allocate(1024);// 4. 发送数据给服务端Scanner scanner = new Scanner(System.in);while (scanner.hasNext()) {String str = scanner.next();String dateStr = new Date().toString() + "\n" +str;byteBuffer.put(dateStr.getBytes());byteBuffer.flip();socketChannel.write(byteBuffer);byteBuffer.clear();}// 5. 关闭通道socketChannel.close();}/*** 服务端*/@Testpublic void server() throws IOException {// 1. 获取通道ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();// 2. 切换非阻塞模式serverSocketChannel.configureBlocking(false);// 3. b绑定连接serverSocketChannel.bind(new InetSocketAddress(9998));// 4. 获取选择器Selector selector = Selector.open();// 5.将通道注册到选择器上serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);// 6. 轮询式的获取选择器上已经“猪呢比就绪”的时间while(selector.select() > 0 ) {// 7.获取当前选择器中,所有注册的"选择件"(已就绪的舰艇)Iterator<SelectionKey> it = selector.selectedKeys().iterator();while(it .hasNext()) {// 8. 获取猪呢比就绪的事件SelectionKey selectionKey = it.next();// 9. 判断具体if (selectionKey.isAcceptable()) {// 10. 若接收就绪,获取客户端连接SocketChannel socketChannel = serverSocketChannel.accept();// 11. 切换非阻塞模式socketChannel.configureBlocking(false);// 12. 将该通道注册到socketChannel.register(selector, SelectionKey.OP_READ);} else if (selectionKey.isReadable()) {// 13. 获取当前选择器上“读就绪,”状态的通道SocketChannel  socketChannel = (SocketChannel) selectionKey.channel();// 14. 读取数据ByteBuffer byteBuffer = ByteBuffer.allocate(1024);int len = 1;while ((len = socketChannel.read(byteBuffer)) > 0) {byteBuffer.flip();System.out.println("----" + new String(byteBuffer.array(),0,len));byteBuffer.clear();}}// 15. 取消选择键it.remove();}}}
}
package com.stu.nio;import org.junit.Test;import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.DatagramChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.util.Date;
import java.util.Iterator;
import java.util.Scanner;public class TestNonBlockingNIO2 {@Testpublic void send() throws IOException {DatagramChannel datagramChannel = DatagramChannel.open();datagramChannel.configureBlocking(false);ByteBuffer byteBuffer = ByteBuffer.allocate(1024);Scanner scanner = new Scanner(System.in);while (scanner.hasNext()){String  str = scanner.next();byteBuffer.put((new Date().toString() + "\n" +str).getBytes());byteBuffer.flip();datagramChannel.send(byteBuffer, new InetSocketAddress("127.0.0.1", 9998));byteBuffer.clear();}datagramChannel.close();}@Testpublic void receive() throws IOException {DatagramChannel datagramChannel = DatagramChannel.open();datagramChannel.configureBlocking(false);datagramChannel.bind(new InetSocketAddress(9998));Selector selector = Selector.open();datagramChannel.register(selector, SelectionKey.OP_READ);while (selector.select() >0) {Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();while (iterator.hasNext()) {SelectionKey selectionKey = iterator.next();if (selectionKey.isReadable()) {ByteBuffer byteBuffer = ByteBuffer.allocate(1024);datagramChannel.receive(byteBuffer);byteBuffer.flip();System.out.println(new String(byteBuffer.array(), 0 , byteBuffer.limit()));byteBuffer.clear();}}iterator.remove();}}}

学自,b站尚硅谷

五、NIO 的非阻塞式网络通信相关推荐

  1. java socket nio 阻塞_Java NIO实现非阻塞式socket通信

    博主知识水平有限,只能提供一个个人的狭隘的理解,如果有新人读到这儿,建议看一下其他教程或者API,如果不明白,再来看一下:如果有dalao读到这儿,希望能指出理解中的问题~谢谢 Java提供了用于网络 ...

  2. java nio非阻塞式网络通信入门案例 (nio服务端与bio多线程客户端(java/python)

    nio服务端: 改进服务端 java客户端 python版本客户端: python客户端改进版(多线程执行) 注意:如果想把服务端程序放在自己的服务器上,要记得开放相应的端口,否则客户端会显示连接超时 ...

  3. java,NIO非阻塞式网络通信DEMO.

    @Testpublic void client() throws IOException {SocketChannel sChannel = SocketChannel.open(new InetSo ...

  4. 五种网络IO模型:阻塞式IO 非阻塞式IO IO复用(IO multiplexing) 信号驱动式IO 异步IO

    文章目录 五种网络IO模型 举例说明 阻塞式I/O模型 非阻塞式I/O I/O多路复用 信号驱动式I/O 异步I/O 比较结果 总结 同步 异步 阻塞 非阻塞 阻塞/非阻塞: 同步/异步: 举例子:小 ...

  5. 系统间通信1:阻塞与非阻塞式通信A

    版权声明:本文引用https://yinwj.blog.csdn.net/article/details/48274255 从这篇博文开始,我们将进入一个新文章系列.这个文章系列专门整理总结了目前系统 ...

  6. 系统间通信1:阻塞与非阻塞式通信B

    版权声明:本文引用https://yinwj.blog.csdn.net/article/details/48274255 接上篇:系统间通信1:阻塞与非阻塞式通信A 4.3 NIO通信框架 目前流行 ...

  7. 阻塞式和非阻塞式udp传输_NIO非阻塞网络编程三大核心理念

    本次开始NIO网络编程,之前已经说过BIO,对于阻塞IO里面的问题一定有了清晰的认识,在JDK1.4版本后,提供了新的JAVA IO操作非阻塞API,用意替换JAVA IO 和JAVA NetWork ...

  8. 阻塞式IO和非阻塞式IO

    什么是阻塞式IO,什么是非阻塞式IO?区分他们有何用? 阻塞式IO:IO即input/output,阻塞式IO指的是"一旦输入/输出工作没有完成,则程序阻塞,直到输入/输出工作完成" ...

  9. Spring WebFlux异步非阻塞式编程

    一.什么是 Spring WebFlux Spring MVC 构建于 Servlet API 之上,使用的是同步阻塞式 I/O 模型,什么是同步阻塞式 I/O 模型呢?就是说,每一个请求对应一个线程 ...

最新文章

  1. flowable设计器节点属性扩展_Flowable-流程定义扩展属性
  2. asyncdata连接php,如何使用Nuxt和asyncData观察路由更改
  3. QT的QFileOpenEvent类的使用
  4. python控制流代码怎么用_Python学习笔记控制流的元素
  5. STL之set_union、set_intersection、set_difference、set_symmetric_difference
  6. java年轻代频繁gc_年轻代频繁ParNew GC,导致http服务rt飙高
  7. 单片机串口实现字符串命令解析
  8. 阿里月薪50k招AI工程师,看到要求我傻眼了!
  9. Android Intent常用方法详细介绍,显示Intent,隐式Intent,调用浏览器,拨号,发短信,传递数据
  10. css 悬停动画_CSS3缩放图像动画效果悬停
  11. java程序: 倒计时的小程序 (GridPane, Timer, Calendar, SimpleDateFormat ...)
  12. 用中位数代替平均数来衡量民生指标
  13. paip.银联支付接口订单号uuid算法
  14. 基金前端代码和后端代码的区别 基金后端代码和基金前端代码区别
  15. js如何实现简繁体互转
  16. 论文阅读笔记|Deep Image Homography Estimation
  17. 虚拟机黑裙加载硬盘_适合练手,在虚拟机中安装黑群晖,想要组建NAS服务器的看这里...
  18. linux为360路由器刷机,[详细]360路由器刷openwrt、不死uboot、双系统 、wifi中继
  19. python-Selenium
  20. ssh-keygen认证密钥

热门文章

  1. kafka Streams
  2. BugKu——Web——社工-初步收集
  3. 【时空点滴系列之1】大公司都喜欢的猥琐动作:尾随时髦小网子。
  4. css实现各种形状,三角形、切角、梯形、五边形、六边形、八边形、五角星
  5. 网页中插入背景音乐的几种方法
  6. 私域流量+小程序,电商引流新机会
  7. mask rcnn只能在linux里运行,1小时上手MaskRCNN·Keras开源实战 | 深度应用
  8. 使用C语言输出* ** *** **** ***** ****** ***** **** *** ** *
  9. 卷积神经网络的卷积及池化(pooling)
  10. 发明专利快速预审多久出结果?