netty中的传输
终于在课设的闲时间把netty实战的四五章给解决了
这里来记录一下第四章里面所讲的IO
首先说到IO,我想,必须要先了解阻塞,非阻塞,同步和异步这四个词
看到一个讲的很易懂的例子:https://www.cnblogs.com/George1994/p/6702084.html
那么了解完这四个词,就到了IO了
传统的IO,即阻塞IO
也就是跟之前用socket编程那样,没有数据写入到来这边的线程就一直等待,直到数据到来然后再对数据进行处理,例如打印
拿出以前的老代码
public void bio(int port) throws IOException{
final ServerSocket socket = new ServerSocket(port);
try {
//死循环,直到有连接再用线程将内容写入
while (true){
Socket client = socket.accept();//阻塞
new Thread(new Runnable() {
@Override
public void run() {
OutputStream out;
try {
out = client.getOutputStream();
out.write("hello world".getBytes(CharsetUtil.UTF_8));
out.flush();
client.close();
}catch (IOException e){
e.printStackTrace();
}finally {
try {
client.close();
}catch (IOException e){
e.printStackTrace();
}
}
}
}).start();
}
}catch (Exception e){
e.printStackTrace();
}
}
传统阻塞IO
代码很容易懂,就是等客户端连接就往里面写入数据,每一个连接对应一个线程去处理,索性采用了多线程,如果是单线程,系统就会阻塞在这里,
多线程CPU在这里能释放做更多事情,的确是个很好的模型,至少我之前一直是这么觉得的...但是似乎这里忽略了一些问题,那就是连接数量的
问题,如果是小量的连接数还是好的,但是如果往大了增加连接数,打个比方一万,那么就会有一万个线程,那么问题就显而易见了,内存这上面就
已经有瓶颈了,而且,线程数量增大,线程之间的切换也会成为一个大问题,因为线程切换的成本很高,有可能线程切换的时间比执行的时间还长,
导致更严重的问题
所以可以知道的是,如果连接量小,那么这个模型是没问题的,如果大了,那么这个就无能为力了
再来说非阻塞IO,即NIO
这是netty实战上的非阻塞IO代码
public void serve(int port) throws IOException {
ServerSocketChannel serverChannel = ServerSocketChannel.open();
serverChannel.configureBlocking(false);//channel设置为非阻塞模式
ServerSocket ss = serverChannel.socket();
InetSocketAddress address = new InetSocketAddress(port);
ss.bind(address);
Selector selector = Selector.open();
serverChannel.register(selector, SelectionKey.OP_ACCEPT);
final ByteBuffer msg = ByteBuffer.wrap("Hi!\r\n".getBytes());
for (;;){
try {
selector.select();//这个函数是阻塞的
} catch (IOException ex) {
ex.printStackTrace();
//handle exception
break;
}
Set<SelectionKey> readyKeys = selector.selectedKeys();
Iterator<SelectionKey> iterator = readyKeys.iterator();
while (iterator.hasNext()) {
SelectionKey key = iterator.next();
iterator.remove();
try {
if (key.isAcceptable()) {
ServerSocketChannel server =
(ServerSocketChannel) key.channel();
SocketChannel client = server.accept();
client.configureBlocking(false);
client.register(selector, SelectionKey.OP_WRITE |
SelectionKey.OP_READ, msg.duplicate());//注册到selector中
System.out.println(
"Accepted connection from " + client);
}
if (key.isWritable()) {
SocketChannel client =
(SocketChannel) key.channel();
ByteBuffer buffer =
(ByteBuffer) key.attachment();
while (buffer.hasRemaining()) {
if (client.write(buffer) == 0) {
break;
}
}
client.close();
}
} catch (IOException ex) {
key.cancel();
try {
key.channel().close();
} catch (IOException cex) {
// ignore on close
}
}
}
}
}
注册当这几个事件到来的时候所对应的处理器。然后在合适的时机告诉事件选择器:对此事件感兴趣。对于写操作,就是写不出去的时候对
写事件感兴趣;对于读操作,就是完成连接和系统没有办法承载新读入的数据的时,对于accept,一般是服务器刚启动的时候;而对于connect,
一般是connect失败需要重连或者异步调用connect的时候,NIO的读写函数可以立刻返回,这就不用另开线程去等待结果了,如果一个连接不能读
写(socket.read()返回0或者socket.write()返回0),就把这件事记下来,记录的方式通常是在Selector上注册标记位,然后切换到其它就绪的连
接(channel)继续进行读写。
这样的优点:相比于阻塞模型,非阻塞不用再等待任务,而是把时间花费到其它任务上,也就是这个当前线程同时处理多个任务,但是也有缺点:
那就是导致任务完成的响应延迟增大了,因为每隔一段时间才去执行询问的动作,但是任务万一在两次询问之间的时间间隔内完成,就会导致整体
数据吞吐量的降低。影响用户体验
Netty中的阻塞和非阻塞
以上是java 里面的NIO,可以看到从阻塞改写到非阻塞这其中还是有很多地方要改的,势必会给带来很多麻烦,下面继续回到netty
而在netty中就不会出现这样的事情了,因为只需改变EventLoopGroup的种类,分别对应的OioEventLoopGroup和NioEventLoppGroup
和channel的种类,对应OioServerSocketChannel和NioServerSocketChannel,其余地方基本不变
Epool,专用于linux的本地非阻塞传输
jdk在linuxl中的NOI的实现上采用了不同的办法,就是使用了epoll调用,他有着比select和poll更好的性能,同时也是linux非阻塞网络编程的事实标准
而且如果程序是运行在linux,也不需要改动很多代码,就跟上面的例子一样,将NioEventLoopGroup和NioServerSocketChannel改成EpollEventLoopGroup
和EpollServerSocketChannel,这一改动在高负载的情况下能比NIO有更好的表现
JVM内部的传输
用于在同一个虚拟机中的客户端和服务端的通信,这个过程中的SocketAddress没有绑定具体的物理网络地址,只要服务器在运行,他就会存储在注册表里,channel关闭
即从表里注销,这里的传输不接收网络流量,其实也能猜出来,毕竟本地,所以他不能和其他我们使用的socket传输互相操作,所以如果客户端想使用本机,即同JVM中的服
务端就必须通过他实现
小结笔记:
IO访问过程:(网络IO本质上就是socket的读取)

对于socket流,就是等待网络上的数据到达,然后复制到图中的缓冲区,然后复制到应用进程
JVM内部通信还有其他几种IO那里还没来得及找例子做一做,找时间再补上,如果错误,还请多多指出
netty中的传输的更多相关文章
- 快来体验快速通道,netty中epoll传输协议详解
目录 简介 epoll的详细使用 EpollEventLoopGroup EpollEventLoop EpollServerSocketChannel EpollSocketChannel 总结 简 ...
- netty系列之:在netty中使用native传输协议
目录 简介 native传输协议的依赖 netty本地传输协议的使用 总结 简介 对于IO来说,除了传统的block IO,使用最多的就是NIO了,通常我们在netty程序中最常用到的就是NIO,比如 ...
- Netty(五)序列化protobuf在netty中的使用
protobuf是google序列化的工具,主要是把数据序列化成二进制的数据来传输用的.它主要优点如下: 1.性能好,效率高: 2.跨语言(java自带的序列化,不能跨语言) protobuf参考文档 ...
- 【转】Netty那点事(二)Netty中的buffer
[原文]https://github.com/code4craft/netty-learning/blob/master/posts/ch2-buffer.md 上一篇文章我们概要介绍了Netty的原 ...
- Netty那点事: 概述, Netty中的buffer, Channel与Pipeline
Netty那点事(一)概述 Netty和Mina是Java世界非常知名的通讯框架.它们都出自同一个作者,Mina诞生略早,属于Apache基金会,而Netty开始在Jboss名下,后来出来自立门户ne ...
- Netty中如何写大型数据
因为网络饱和的可能性,如何在异步框架中高效地写大块的数据是一个特殊的问题.由于写操作是非阻塞的,所以即使没有写出所有的数据,写操作也会在完成时返回并通知ChannelFuture.当这种情况发生时,如 ...
- Netty中的基本组件及关系
原文:https://blog.csdn.net/summerZBH123/article/details/79344226--------------------- 概述 这篇文章主要是用来 ...
- Netty中ByteBuf 的零拷贝
转载:https://www.jianshu.com/p/1d1fa2fe1ed9 此文章已同步发布在我的 segmentfault 专栏. 根据 Wiki 对 Zero-copy 的定义: &quo ...
- Netty 中ChannelOption的含义以及使用的场景
Netty 中ChannelOption的含义以及使用的场景 转自:http://www.cnblogs.com/googlemeoften/p/6082785.html 1.ChannelOptio ...
随机推荐
- g++编译X265
自己参考用: msys2 编译X265的命令 编译用工具安装 pacman -S git make tar automake autoconf libtool pkg-config mingw-w64 ...
- 【JavaWeb】防止表单的重复提交
https://www.cnblogs.com/yfsmooth/p/4516779.html 看了以下别人给的总结: 客户端上防止提交: 1.js控制阻止 2.设置HTTP报头,控制表单缓存,使得所 ...
- C# ListView应用
C# ListView应用 1. 添加表头标题的方法 a. 直接在ListView控件上编写 b. 通过代码编写 //动态添加lstv_ReaderList列表头 /* lstv_ReaderLis ...
- 前端页面播放 rtmp 流与 flv 格式视频文件
技术 :angular/cli , html5 , typescript , scss ,es 6 ... 项目类型:直播视频与视频回放 使用到 插件 : videojs + ckplayer 遇到的 ...
- 解决mysql for docker容器报错:Authentication plugin 'caching_sha2_password' cannot be loaded
为图方便,懒得在mac上安装mysql了,一个是管理不方便,第二个是为了方便多机器同步开发环境.就使用docker安装了. 拉取mysql镜像 docker pull mysql 运行mysql实例 ...
- GXB动态重配置
可选择重配置逻辑(Optional Reconfiguration Logic) 使能选项: • Capability registers • Control and status registers ...
- Eclipse下用NDK编译生成so文件
我们在安装环境的时候安装了NDK,可以在eclipse下直接生成so文件.NDK的压缩包里面自带了一些sample工程,NDK的文件直接解压到某个目录下即可. 第一次生成so文件的时候,我们先使用 ...
- 画PCB之电流与线宽的关系
来源:(多图) 超强整理!PCB设计之电流与线宽的关系http://www.51hei.com/bbs/dpj-39134-1.html 关于PCB线宽和电流的经验公式,关系表和软件网上都很多,本文把 ...
- tarjan算法总结
部分内容引自https://www.cnblogs.com/stxy-ferryman/p/7779347.html Tarjan算法不是一个算法而是一类算法 1.求取强连通分量 强连通分量————有 ...
- 8-unittest中case管理
1.关联 在接口测试中难免碰到接口B的参数值来源于接口A的返回结果,此现象即为关联.在unittest中怎么处理这种情况呢?此问题通过全局变量来解决,将变量定义为全局变量:globals()[‘var ...