【对线面试官】Java NIO
服务端:
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的更多相关文章
- 【对线面试官】Java 反射&&动态代理
// 抽象类,定义泛型<T> public abstract class BaseDao<T> { public BaseDao(){ Class clazz = this.g ...
- 【对线面试官】Java多线程基础
// 请求直接交给线程池来处理 public void push(PushParam pushParam) { try { pushServiceThreadExecutor.submit(() -& ...
- 【对线面试官】CountDownLatch和CyclicBarrier的区别
<对线面试官>系列目前已经连载31篇啦,这是一个讲人话面试系列 [对线面试官]Java注解 [对线面试官]Java泛型 [对线面试官] Java NIO [对线面试官]Java反射 &am ...
- 【对线面试官】Kafka基础入门
<对线面试官>系列目前已经连载33篇啦,这是一个讲人话面试系列 [对线面试官]Java注解 [对线面试官]Java泛型 [对线面试官] Java NIO [对线面试官]Java反射 &am ...
- 浅谈MySQL日志文件|手撕MySQL|对线面试官
关注微信公众号[程序员白泽],进入白泽的知识分享星球 前言 上周五面试了字节的第三面,深感数据库知识的重要,我也意识到在平时的学习中,自己对于数据库的学习较为薄弱.甚至在有过一定实习经验之后,依旧因为 ...
- 对线面试官,凭借nginx能一战封神吗?
面试官:小伙子,你对nginx熟悉吗? 我:当然熟悉了,请听我慢慢道来. 心里想,我能吊打面试官吗?今天非得灭一灭面试官的威风,平时都被怼的狗血淋头. 面试官:就你那点花花肠子,咱还不清楚. 我:.. ...
- 【对线面试官】Java注解
public void send(String userName) { try { // qps 上报 qps(params); long startTime = System.c ...
- 面试中的MySQL主从复制|手撕MySQL|对线面试官
关注微信公众号[程序员白泽],进入白泽的知识分享星球 前言 作为<手撕MySQL>系列的第三篇文章,今天讲解使用bin log实现主从复制的功能.主从复制也是MySQL集群实现高可用.数据 ...
- MySQL通过bin log日志恢复数据|手撕MySQL|对线面试官
关注微信公众号[程序员白泽],进入白泽的知识分享星球 前言 作为<手撕MySQL>系列的第二篇文章,今天介绍一下MySQL的二进制日志(bin log),注意不要和MySQL的InnoDB ...
随机推荐
- Linux里的几种不同的压缩命令小记
第一个是 .gz的压缩格式 我们使用gzip来对文件进行压缩,使用gunzip(或者是gzip -d)来对文件进行解压缩 但是gzip的缺点在于不能够压缩目录,压缩的时候也不能够保留源文件 第二个是 ...
- 用STM32定时器测量信号频率——测频法和测周法[原创cnblogs.com/helesheng]
工业测试与控制系统中,经常需要对未知信号的频率进行测试.对于10MHz以下的信号,用单片机(MCU)定时器完成这项任务显然是最常见和最佳的选择.目前性价比最高的单片机STM32拥有功能强大且数量众多的 ...
- 事后Postmortem会议
会议图片 一.设想和目标 1. 我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述? 我的软件是要建立一个失物招领网站,是一个为校园里的失误招领工作提供便利的平台.我们对 ...
- 个人项目作业--WC的实现
GitHub项目地址 https://github.com/1721819634/WC 1.Word Count 项目要求: wc.exe 是一个常见的工具,它能统计文本文件的字符数.单词数和行数. ...
- 手写线程池,对照学习ThreadPoolExecutor线程池实现原理!
作者:小傅哥 博客:https://bugstack.cn Github:https://github.com/fuzhengwei/CodeGuide/wiki 沉淀.分享.成长,让自己和他人都能有 ...
- 5+App 相关记录
一.页面跳转到app 1.应用的manifest.json文件,plus --> distribute --> google 节点下,增加属性 schemes 2.打包后,在手机里安装. ...
- 编译opencv4.5.0
1. 环境vs2017或其它版本cmake-3.18设置环境变量OPENCV_TEST_DATA_PATH 值设置为 D:\sdk\vs2017\opencv-4.5.0\opencv_extra-4 ...
- dataframe,list,numpy之间的互相转换
dataframe,numpy,list之间的互相转换 由于目前学校要做一些数据分析处理的作业有要用到dataframe,list,numpy之间的转化,所以在此总结一下这些用法. dataframe ...
- 注解 @CrossOrigin
在Controller中看到@CrossOrigin ,这是什么?有什么用?为什么要用? what? @CrossOrigin是用来处理跨域请求的注解 先来说一下什么是跨域: (站在巨人的肩膀上) 跨 ...
- s2-061 漏洞复现
0x00 漏洞简介 Apache Struts2框架是一个用于开发Java EE网络应用程序的Web框架.Apache Struts于2020年12月08日披露 S2-061 Struts 远程代码执 ...