服务端:

public class NoBlockServer {

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

        // 1.获取通道
ServerSocketChannel server = ServerSocketChannel.open(); // 2.切换成非阻塞模式
server.configureBlocking(false); // 3. 绑定连接
server.bind(new InetSocketAddress(6666)); // 4. 获取选择器
Selector selector = Selector.open(); // 4.1将通道注册到选择器上,指定接收“监听通道”事件
server.register(selector, SelectionKey.OP_ACCEPT); // 5. 轮训地获取选择器上已“就绪”的事件--->只要select()>0,说明已就绪
while (selector.select() > 0) {
// 6. 获取当前选择器所有注册的“选择键”(已就绪的监听事件)
Iterator<SelectionKey> iterator = selector.selectedKeys().iterator(); // 7. 获取已“就绪”的事件,(不同的事件做不同的事)
while (iterator.hasNext()) { SelectionKey selectionKey = iterator.next(); // 接收事件就绪
if (selectionKey.isAcceptable()) { // 8. 获取客户端的链接
SocketChannel client = server.accept(); // 8.1 切换成非阻塞状态
client.configureBlocking(false); // 8.2 注册到选择器上-->拿到客户端的连接为了读取通道的数据(监听读就绪事件)
client.register(selector, SelectionKey.OP_READ); } else if (selectionKey.isReadable()) { // 读事件就绪 // 9. 获取当前选择器读就绪状态的通道
SocketChannel client = (SocketChannel) selectionKey.channel(); // 9.1读取数据
ByteBuffer buffer = ByteBuffer.allocate(1024); // 9.2得到文件通道,将客户端传递过来的图片写到本地项目下(写模式、没有则创建)
FileChannel outChannel = FileChannel.open(Paths.get("2.png"), StandardOpenOption.WRITE, StandardOpenOption.CREATE); while (client.read(buffer) > 0) {
// 在读之前都要切换成读模式
buffer.flip(); outChannel.write(buffer); // 读完切换成写模式,能让管道继续读取文件的数据
buffer.clear();
}
}
// 10. 取消选择键(已经处理过的事件,就应该取消掉了)
iterator.remove();
}
} }
}

客户端:

public class NoBlockClient {

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

        // 1. 获取通道
SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1", 6666)); // 1.1切换成非阻塞模式
socketChannel.configureBlocking(false); // 1.2获取选择器
Selector selector = Selector.open(); // 1.3将通道注册到选择器中,获取服务端返回的数据
socketChannel.register(selector, SelectionKey.OP_READ); // 2. 发送一张图片给服务端吧
FileChannel fileChannel = FileChannel.open(Paths.get("X:\\Users\\ozc\\Desktop\\面试造火箭\\1.png"), StandardOpenOption.READ); // 3.要使用NIO,有了Channel,就必然要有Buffer,Buffer是与数据打交道的呢
ByteBuffer buffer = ByteBuffer.allocate(1024); // 4.读取本地文件(图片),发送到服务器
while (fileChannel.read(buffer) != -1) { // 在读之前都要切换成读模式
buffer.flip(); socketChannel.write(buffer); // 读完切换成写模式,能让管道继续读取文件的数据
buffer.clear();
} // 5. 轮训地获取选择器上已“就绪”的事件--->只要select()>0,说明已就绪
while (selector.select() > 0) {
// 6. 获取当前选择器所有注册的“选择键”(已就绪的监听事件)
Iterator<SelectionKey> iterator = selector.selectedKeys().iterator(); // 7. 获取已“就绪”的事件,(不同的事件做不同的事)
while (iterator.hasNext()) { SelectionKey selectionKey = iterator.next(); // 8. 读事件就绪
if (selectionKey.isReadable()) { // 8.1得到对应的通道
SocketChannel channel = (SocketChannel) selectionKey.channel(); ByteBuffer responseBuffer = ByteBuffer.allocate(1024); // 9. 知道服务端要返回响应的数据给客户端,客户端在这里接收
int readBytes = channel.read(responseBuffer); if (readBytes > 0) {
// 切换读模式
responseBuffer.flip();
System.out.println(new String(responseBuffer.array(), 0, readBytes));
}
} // 10. 取消选择键(已经处理过的事件,就应该取消掉了)
iterator.remove();
}
}
} }

文章以纯面试的角度去讲解,所以有很多的细节是未铺垫的。

鉴于很多同学反馈没看懂【对线面试官】系列,基础相关的知识我确实写过文章讲解过啦,但有的同学就是不爱去翻。

为了让大家有更好的体验,我把基础文章也找出来(重要的知识点我还整理过电子书,比如说像多线程、集合这种面试必考的早就已经转成PDF格式啦)

我把这些上传到网盘,你们有需要直接下载就好了。做到这份上了,不会还想白嫖吧点赞转发又不用钱。

链接:https://pan.baidu.com/s/1pQTuKBYsHLsUR5ORRAnwFg 密码:3wom

欢迎关注我的微信公众号【Java3y】来聊聊Java面试

【对线面试官】Java NIO的更多相关文章

  1. 【对线面试官】Java 反射&&动态代理

    // 抽象类,定义泛型<T> public abstract class BaseDao<T> { public BaseDao(){ Class clazz = this.g ...

  2. 【对线面试官】Java多线程基础

    // 请求直接交给线程池来处理 public void push(PushParam pushParam) { try { pushServiceThreadExecutor.submit(() -& ...

  3. 【对线面试官】CountDownLatch和CyclicBarrier的区别

    <对线面试官>系列目前已经连载31篇啦,这是一个讲人话面试系列 [对线面试官]Java注解 [对线面试官]Java泛型 [对线面试官] Java NIO [对线面试官]Java反射 &am ...

  4. 【对线面试官】Kafka基础入门

    <对线面试官>系列目前已经连载33篇啦,这是一个讲人话面试系列 [对线面试官]Java注解 [对线面试官]Java泛型 [对线面试官] Java NIO [对线面试官]Java反射 &am ...

  5. 浅谈MySQL日志文件|手撕MySQL|对线面试官

    关注微信公众号[程序员白泽],进入白泽的知识分享星球 前言 上周五面试了字节的第三面,深感数据库知识的重要,我也意识到在平时的学习中,自己对于数据库的学习较为薄弱.甚至在有过一定实习经验之后,依旧因为 ...

  6. 对线面试官,凭借nginx能一战封神吗?

    面试官:小伙子,你对nginx熟悉吗? 我:当然熟悉了,请听我慢慢道来. 心里想,我能吊打面试官吗?今天非得灭一灭面试官的威风,平时都被怼的狗血淋头. 面试官:就你那点花花肠子,咱还不清楚. 我:.. ...

  7. 【对线面试官】Java注解

    public void send(String userName) {  try {    // qps 上报    qps(params);    long startTime = System.c ...

  8. 面试中的MySQL主从复制|手撕MySQL|对线面试官

    关注微信公众号[程序员白泽],进入白泽的知识分享星球 前言 作为<手撕MySQL>系列的第三篇文章,今天讲解使用bin log实现主从复制的功能.主从复制也是MySQL集群实现高可用.数据 ...

  9. MySQL通过bin log日志恢复数据|手撕MySQL|对线面试官

    关注微信公众号[程序员白泽],进入白泽的知识分享星球 前言 作为<手撕MySQL>系列的第二篇文章,今天介绍一下MySQL的二进制日志(bin log),注意不要和MySQL的InnoDB ...

随机推荐

  1. Linux里的几种不同的压缩命令小记

    第一个是 .gz的压缩格式 我们使用gzip来对文件进行压缩,使用gunzip(或者是gzip -d)来对文件进行解压缩 但是gzip的缺点在于不能够压缩目录,压缩的时候也不能够保留源文件 第二个是 ...

  2. 用STM32定时器测量信号频率——测频法和测周法[原创cnblogs.com/helesheng]

    工业测试与控制系统中,经常需要对未知信号的频率进行测试.对于10MHz以下的信号,用单片机(MCU)定时器完成这项任务显然是最常见和最佳的选择.目前性价比最高的单片机STM32拥有功能强大且数量众多的 ...

  3. 事后Postmortem会议

    会议图片 一.设想和目标 1. 我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述? 我的软件是要建立一个失物招领网站,是一个为校园里的失误招领工作提供便利的平台.我们对 ...

  4. 个人项目作业--WC的实现

     GitHub项目地址 https://github.com/1721819634/WC 1.Word Count 项目要求: wc.exe 是一个常见的工具,它能统计文本文件的字符数.单词数和行数. ...

  5. 手写线程池,对照学习ThreadPoolExecutor线程池实现原理!

    作者:小傅哥 博客:https://bugstack.cn Github:https://github.com/fuzhengwei/CodeGuide/wiki 沉淀.分享.成长,让自己和他人都能有 ...

  6. 5+App 相关记录

    一.页面跳转到app 1.应用的manifest.json文件,plus --> distribute --> google 节点下,增加属性 schemes 2.打包后,在手机里安装. ...

  7. 编译opencv4.5.0

    1. 环境vs2017或其它版本cmake-3.18设置环境变量OPENCV_TEST_DATA_PATH 值设置为 D:\sdk\vs2017\opencv-4.5.0\opencv_extra-4 ...

  8. dataframe,list,numpy之间的互相转换

    dataframe,numpy,list之间的互相转换 由于目前学校要做一些数据分析处理的作业有要用到dataframe,list,numpy之间的转化,所以在此总结一下这些用法. dataframe ...

  9. 注解 @CrossOrigin

    在Controller中看到@CrossOrigin ,这是什么?有什么用?为什么要用? what? @CrossOrigin是用来处理跨域请求的注解 先来说一下什么是跨域: (站在巨人的肩膀上) 跨 ...

  10. s2-061 漏洞复现

    0x00 漏洞简介 Apache Struts2框架是一个用于开发Java EE网络应用程序的Web框架.Apache Struts于2020年12月08日披露 S2-061 Struts 远程代码执 ...