基于NIO写的阻塞式和非阻塞式的客户端服务端
由于功能太过简单,就不过多阐述了,直接上阻塞式代码:
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 { } } }
基于NIO写的阻塞式和非阻塞式的客户端服务端的更多相关文章
- NIO之阻塞IO与非阻塞IO(包含Selector使用)
阻塞IO 传统的 IO 流都是阻塞式的. 也就是说,当一个线程调用 read() 或 write()时,该线程被阻塞,直到有一些数据被读取或写入,该线程在此期间不能执行其他任务. 因此,在完成网络通信 ...
- 如何解读 Java IO、NIO 中的同步阻塞与同步非阻塞?
原文链接:如何解读 Java IO.NIO 中的同步阻塞与同步非阻塞? 一.前言 最近刚读完一本书:<Netty.Zookeeper.Redis 并发实战>,个人觉得 Netty 部分是写 ...
- 阻塞式和非阻塞式IO
有很多人把阻塞认为是同步,把非阻塞认为是异步:个人认为这样是不准确的,当然从思想上可以这样类比,但方式是完全不同的,下面说说在JAVA里面阻塞IO和非阻塞IO的区别 在JDK1.4中引入了一个NIO的 ...
- Java网络编程和NIO详解5:Java 非阻塞 IO 和异步 IO
Java网络编程和NIO详解5:Java 非阻塞 IO 和异步 IO Java 非阻塞 IO 和异步 IO 转自https://www.javadoop.com/post/nio-and-aio 本系 ...
- 【死磕NIO】— 阻塞IO,非阻塞IO,IO复用,信号驱动IO,异步IO,这你真的分的清楚吗?
通过上篇文章([死磕NIO]- 阻塞.非阻塞.同步.异步,傻傻分不清楚),我想你应该能够区分了什么是阻塞.非阻塞.异步.非异步了,这篇文章我们来彻底弄清楚什么是阻塞IO,非阻塞IO,IO复用,信号驱动 ...
- Java基础知识强化之多线程笔记07:同步、异步、阻塞式、非阻塞式 的联系与区别
1. 同步: 所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回.但是一旦调用返回,就必须先得到返回值了. 换句话话说,调用者主动等待这个"调用"的结果. 对于 ...
- 什么是阻塞式和非阻塞io流?
阻塞IO:socket 的阻塞模式意味着必须要做完IO 操作(包括错误)才会返回. 非阻塞IO:非阻塞模式下无论操作是否完成都会立刻返回,需要通过其他方式来判断具体操作是否成功. 两者区别: 所谓阻塞 ...
- 网络IO模型:同步IO和异步IO,阻塞IO和非阻塞IO
同步(synchronous) IO和异步(asynchronous) IO,阻塞(blocking) IO和非阻塞(non-blocking)IO分别是什么,到底有什么区别?这个问题其实不同的人给出 ...
- 转 网络IO模型:同步IO和异步IO,阻塞IO和非阻塞IO
此文章为转载,如有侵权,请联系本人.转载出处,http://blog.chinaunix.net/uid-28458801-id-4464639.html 同步(synchronous) IO和异步( ...
- 阻塞IO、非阻塞IO的区别
1.类与类之间的关系:依赖,实现,泛化(继承),关联,组合,聚合. 1)依赖(虚线):一个类是 另一个类的函数参数 或者 函数返回值. 2)实现(实线加小圆):对纯虚函数类(抽象类)的实现. 3)继承 ...
随机推荐
- Flask-第三方插件
Flask-Session 因为flask自带的session是将session存在cookie中: 所以才有了第三方Flask_session插件,可以将session存储在我们想存储的数据库中(r ...
- webpack - 优化阻塞渲染的css
随着浏览器的日新月异,网页的性能和速度越来越好,并且对于用户体验来说也越来越重要. 现在有很多优化页面的办法,比如:静态资源的合并和压缩,code splitting,DNS预读取等等. 本文介绍的是 ...
- Python学习日记(六)——内置函数和文件操作(lambda)
lambda表达式 学习条件运算时,对于简单的 if else 语句,可以使用三元运算来表示,即: # 普通条件语句 if 1 == 1: name = 'prime' else: name = 'c ...
- git reset 版本回退操作
1 git回退命令 git reset --hard GIT_HEAD GIT_HEAD是你具体要回退的分支: 如图: 注: 查询GIT_HEAD可以通过两个命令:git log 获取未删除 ...
- zip flags 1 and 8 are not supported解决方案
原因是因为使用了mac自带的软件打包成了zip,这种zip包unzip命令无法解压的. 所以解决方案就是使用zip命令进行压缩,zip -r 目标文件 源文件
- Maven:禁止编码指定类型的资源文件
[参考文章]:项目编译后dll文件调用出错 maven 在编译或项目时,可能会对资源文件进二次编码(编译前后的文件大小对比即可发现该问题),有些文件(例如:文本文件)可能不会影响我们是用,但是有些文件 ...
- Kotlin 中类函数
在kotlin中函数可以在类外部定义也可以在类内部定义,前者即为全局函数,后者,是类成员函数,语法一样 package loaderman.demo class Person { fun demo(n ...
- test result
- 阶段5 3.微服务项目【学成在线】_day05 消息中间件RabbitMQ_11.RabbitMQ研究-工作模式-路由工作模式测试
先常见生产者 复制02的代码 先改一下交换机的名称 还需要制定routingKey.因为是两个消息 所以指定了两个routingKey 这里修改为当前指定的交换机名称 交换机和队列在绑定的时候指定我们 ...
- 图解 HTTP 笔记(四)——HTTP 状态码
本章主要内容是了解 HTTP 状态码的工作机制 状态码的职责是当客户端向服务器端发送请求时,描述返回的请求结果.借助状态码,我们可以了解这次请求是否在服务器端得到了正常的处理. 状态码从其含以上可以分 ...