- 浏览: 229518 次
- 性别:
- 来自: 广州
文章分类
最新评论
-
tonyyan:
谢谢分享!
Kafka 监控 -
dtyu100:
反手就是一个赞,这相当于是官网druid.io的中文版本,很厉 ...
Druid 大数据分析之快速应用(单机模式) -
sqy:
2018-04-12T01:30:27,527 ERROR [ ...
Druid 大数据分析之快速应用(单机模式) -
wangyudong:
学习了,不错的Spring boot实例,参考着很快写出了RE ...
Spring boot 入门实例 -
string2020:
servlet4规范出来了,求翻译
Java Servlet3.1规范
传统IO 写道
网络传输方式问题:传统的RPC框架或者基于RMI等方式的远程服务(过程)调用采用了同步阻塞IO,当客户端的并发压力或者网络时延增大之后,同步阻塞IO会由于频繁的wait导致IO线程经常性的阻塞,由于线程无法高效的工作,IO处理能力自然下降。下面,我们通过BIO通信模型图看下BIO通信的弊端:
采用BIO通信模型的服务端,通常由一个独立的Acceptor线程负责监听客户端的连接,接收到客户端连接之后为客户端连接创建一个新的线程处理请求消息,处理完成之后,返回应答消息给客户端,线程销毁,这就是典型的一请求一应答模型。该架构最大的问题就是不具备弹性伸缩能力,当并发访问量增加后,服务端的线程个数和并发访问数成线性正比,由于线程是JAVA虚拟机非常宝贵的系统资源,当线程数膨胀之后,系统的性能急剧下降,随着并发量的继续增加,可能会发生句柄溢出、线程堆栈溢出等问题,并导致服务器最终宕机。
NIO 写道
在IO编程过程中,当需要同时处理多个客户端接入请求时,可以利用多线程或者IO多路复用技术进行处理。IO多路复用技术通过把多个IO的阻塞复用到同一个select的阻塞上,从而使得系统在单线程的情况下可以同时处理多个客户端请求。与传统的多线程/多进程模型比,I/O多路复用的最大优势是系统开销小,系统不需要创建新的额外进程或者线程,也不需要维护这些进程和线程的运行,降低了系统的维护工作量,节省了系统资源。
JDK1.4提供了对非阻塞IO(NIO)的支持,JDK1.5_update10版本使用epoll替代了传统的select/poll,极大的提升了NIO通信的性能。
JAVA NIO实现服务端与客户端简单数据传输
import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.ClosedChannelException; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.util.Iterator; /** * 服务端 */ public class SocketServer { /** * 服务器默认绑定端口 */ public static final int DEFAULT_PORT = 9999; /** * 选择器 */ public Selector selector; public SocketServer(String ip, int port) { ServerSocketChannel ssc = null; try { int _port = DEFAULT_PORT; if (port > 0) _port = port; /* 获取通道 */ ssc = ServerSocketChannel.open(); /* 配置非阻塞 */ ssc.configureBlocking(false); /** * 配置绑定端口 ServerSocketChannel没有bind()方法, * 因此有必要取出对等的ServerSocket并使用它来绑定到一 * 个端口以开始监听连接 */ ssc.socket().bind(new InetSocketAddress(ip, _port)); /* 获取选择器 */ this.selector = Selector.open(); /* 将通道注册到选择器 */ ssc.register(this.selector, SelectionKey.OP_ACCEPT); }catch(ClosedChannelException e1){ System.out.println("关闭的通道,无法注册到选择器"); e1.printStackTrace(); } catch (IOException e2) { try { if(ssc != null) ssc.close(); } catch (IOException e) { e.printStackTrace(); } System.out.println("服务器绑定端口冲突"); e2.printStackTrace(); } } /** * 轮询选择器 * @throws Exception */ public void pollSelect() throws Exception { /* (阻塞)轮询选择器,直到有事件 */ while (this.selector.select()>0) { /* 获取事件通知列表 */ Iterator<SelectionKey> it = this.selector.selectedKeys().iterator(); while (it.hasNext()) { SelectionKey selectKey = it.next(); it.remove(); try { process(selectKey); } catch (Exception e) { e.printStackTrace(); continue; } } } } /** * 事件处理 * @param selectKey */ public void process(SelectionKey selectKey) throws Exception{ if (selectKey.isAcceptable()) { /* 客户端连接事件 */ accept(selectKey); } else if (selectKey.isReadable()) { /* 可读事件 */ read(selectKey); } } /** * 连接事件 * @param selectKey */ public void accept(SelectionKey selectKey) throws Exception { ServerSocketChannel ssc = null; try { ssc = (ServerSocketChannel) selectKey .channel(); SocketChannel sc = ssc.accept(); sc.configureBlocking(false); /* 发送信息 */ sc.write(ByteBuffer.wrap(new String("Hello World!") .getBytes())); /* 注册读事件 */ sc.register(this.selector, SelectionKey.OP_READ); } catch (ClosedChannelException e) { if(ssc!=null) ssc.close(); throw new IOException("关闭的通道,无法注册到选择器"); } catch (IOException e) { if(ssc!=null) ssc.close(); throw new IOException("连接服务或配置失败!"); } } /** * 可读事件 * @param selectKey */ public void read(SelectionKey selectKey) throws Exception{ SocketChannel channel = null; try { // 服务器可读取消息:得到事件发生的Socket通道 channel = (SocketChannel) selectKey.channel(); // 创建读取的缓冲区 ByteBuffer buffer = ByteBuffer.allocate(100); channel.read(buffer); byte[] data = buffer.array(); String msg = new String(data).trim(); System.out.println("客户端:" + msg); // ByteBuffer outBuffer = ByteBuffer.wrap(msg.getBytes()); // 将消息回送给客户端 // channel.write(outBuffer); } catch (Exception e) { if(channel != null) channel.close(); throw new Exception("客户端将通道关闭,无法从通道读入缓冲或将缓冲数据写回通道!"); } } public static void main(String[] args) { SocketServer ss = null; try { ss = new SocketServer("localhost", 9999); ss.pollSelect(); } catch (Exception e) { e.printStackTrace(); } } }
import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.ClosedChannelException; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.SocketChannel; import java.util.Iterator; /** * 客户端 */ public class SocketClient { public Selector selector; public SocketClient(String ip, int port){ SocketChannel channel = null; try { //channel = SocketChannel.open(new InetSocketAddress(ip,port)); channel = SocketChannel.open(); // 设置通道为非阻塞 channel.configureBlocking(false); // 获得一个通道管理器 this.selector = Selector.open(); // 客户端连接服务器,其实方法执行并没有实现连接 channel.connect(new InetSocketAddress(ip, port)); /**while(!channel.finishConnect()){ System.out.println("尝试连接...."); }*/ // 注册连接事件。 channel.register(this.selector, SelectionKey.OP_CONNECT); } catch(ClosedChannelException e1){ System.out.println("关闭的通道,无法注册到选择器"); e1.printStackTrace(); } catch (IOException e2) { System.out.println("连接异常!"); try { if(channel != null) channel.close(); } catch (IOException e) { e.printStackTrace(); } e2.printStackTrace(); } } /** * 轮询选择器 * @throws IOException */ public void pollSelect() throws Exception { /* (阻塞)轮询选择器,直到有事件 */ while ( this.selector.select() > 0 ) { /* 获取事件通知列表 */ Iterator<SelectionKey> ite = this.selector.selectedKeys().iterator(); while (ite.hasNext()) { SelectionKey selectKey = (SelectionKey) ite.next(); // 删除已选的key,以防重复处理 ite.remove(); process(selectKey); } } } /** * 处理事件 * @param selectKey */ public void process(SelectionKey selectKey) throws Exception{ if (selectKey.isConnectable()) { connect(selectKey); } else if (selectKey.isReadable()) { read(selectKey); } } /** * 连接事件 * @param selectKey * @throws Exception */ public void connect(SelectionKey selectKey) throws Exception{ try { SocketChannel channel = (SocketChannel) selectKey .channel(); /* 如果正在连接,则完成连接 */ if(channel.isConnectionPending()){ /** * connect()方法尚未被调用,调用finishConnect()方法, * 那么将产生NoConnectionPendingException */ channel.finishConnect(); } /** * 在非阻塞模式下调用connect()方法之后,SocketChannel又被切换回了阻塞模式;那么如果 * 有必要的话,调用线程会阻塞直到连接建立完成,finishConnect()方法接着就会返回true * 值。 */ /* 设置成非阻塞 */ channel.configureBlocking(false); /* 给服务端发送信息 */ channel.write(ByteBuffer.wrap(new String("编号001客户端连接成功!").getBytes())); /* 注册读事件 */ channel.register(this.selector, SelectionKey.OP_READ); } catch (ClosedChannelException e) { throw new IOException("关闭的通道,无法注册到选择器"); } catch (IOException e) { throw new IOException("连接服务或配置失败!"); } } /** * 读事件 * @param selectKey * @throws Exception */ public void read(SelectionKey selectKey) throws Exception{ try { // 服务器可读通道 SocketChannel channel = (SocketChannel) selectKey.channel(); // 创建读取的缓冲区 ByteBuffer buffer = ByteBuffer.allocate(100); channel.read(buffer); byte[] data = buffer.array(); String msg = new String(data).trim(); System.out.println(msg); ByteBuffer outBuffer = ByteBuffer.wrap(msg.getBytes()); // 将消息回送给服务端 //channel.write(outBuffer); } catch (Exception e) { throw new IOException("服务端将通道关闭,无法从通道读入缓冲或将缓冲数据写回通道!"); } } public static void main(String[] args) { SocketClient sc = null; try { sc = new SocketClient("localhost", 9999); sc. pollSelect(); } catch (Exception e) { e.printStackTrace(); } } }
发表评论
-
数据接入ElasticSearch方式培训PPT
2018-01-28 11:53 1841写道 数据接入ElasticSearch几种方式总结,涉及 ... -
Apache ftp tools 图片下载支持中文
2017-12-05 23:55 1208写道 Apache Commom net:1) 递归pat ... -
FtpURLConnection 图片下载编码问题
2017-12-05 23:13 818写道 问题:1)Web项目中下载图片,存在下载不全,丢失部 ... -
Kafka 监控
2017-11-18 00:31 5668背景概述 写道 kafka0.9及以前版本ka ... -
Spring Cloud之OAuth2
2017-07-08 12:04 11296备:附件中OAuth2 授权服务器实现源码及PPT 一 ... -
Spring Cloud之Configuration Server
2017-05-19 22:51 1463为什么用spring cloud config 写道 一 ... -
Java Servlet3.1规范
2016-11-25 20:33 1162目录 前言........................ ... -
JMX监控(MBean)
2016-11-23 22:16 4068一、引言 写道 随着企业 IT 规模的不断增长,IT 资 ... -
哈希表在JAVA中如何实现
2016-11-23 20:42 2872一、 复习一下基础知识 1. 截断低位与抹除高位 ... -
Spring boot 入门实例
2016-10-29 00:33 4825写道 Spring Boot是由Pivotal团队提供的全 ... -
Java计算两点经纬度距离及最短运行时间
2016-09-12 21:20 2497概述 经纬度在地图应用中常见,一般结合路网信息库, ... -
计算机软件开源技术、大数据技术等资源教程
2016-08-24 13:01 539基于时间序列化数据引擎排名,很多OLAP工具,根据自身业务 ... -
代码单元与代码点
2016-08-16 17:46 638代码单元与代码点 代码点指编码表(比如Unicode)中某 ... -
Java模块化解决方案
2016-08-15 00:19 4136网络上很多OSGi的文章上来就Activator实例, ... -
深入浅出ClassLoader
2016-08-13 17:06 721你真的了解ClassLoader吗? 这篇文章翻译自zer ... -
Generate axis server code from wsdl
2016-08-04 00:34 12111、为什么需要生成服 ... -
Spring DAO设计实战
2016-01-23 12:21 3204引用 提供不同数据源和方言实现智能分页,因Spring单例 ... -
JAVA NIO 之三
2016-01-17 00:35 1683引用 本节采用JDK1.5之后java.util.con ... -
JAVA NIO 之二
2016-01-14 00:35 1930引用 继上节利用JAVA NIO实现简单数据传,本节实现自定 ... -
JAVA压缩图片并打成ZIP
2016-01-06 13:48 7348引用 JAVA 获取网络图片或本地图片压缩后打成ZIP,但 ...
相关推荐
05-Java NIO-Channel-FileChannel详解(一).mp4 06-Java NIO-Channel-FileChannel详解(二).mp4 07-Java NIO-Channel-Socket通道-概述.mp4 08-Java NIO-Channel-ServerSocketChannel.mp4 09-Java NIO-Channel-...
[第4节] JavaNIO流-通道1.flv [第5节] Java NIO流-通道2.flv [第6节] Java NIO流-socket通道操作.flv [第7节] Java NIO流-文件通道操作.flv [第8节] Java NIO流-选择器 .flv [第9节] Java NIO流-选择器操作.flv...
jsch-nio, 通过SSH实现 Java nio 文件系统 jsch-nio注意,这个项目依赖于 jsch扩展插件项目JSch是利用JSch实现实现一个 nio 文件系统,以及它随之一起运行的所有方法。 到目前为止,有一个功能齐全的unix/linux ...
NULL 博文链接:https://maoyidao.iteye.com/blog/1149015
下面小编就为大家带来一篇JAVA-NIO之Socket/ServerSocket Channel(详解)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
下面小编就为大家分享一篇JDK1.7 之java.nio.file.Files 读取文件仅需一行代码实现,具有很好的参考价值,希望对大家有所帮助
7.1 打开一个FileChannel 7.2 从FileChannel通道中读取数据 7.3 向FileChannel中写入数据: 7.4 关闭FileCha
Java中的IO与NIO面试题 Java反射面试题 Java序列化面试题 Java注解面试题 多线程&并发面试题 JVM面试题 Mysql面试题 Redis面试题 Memcached面试题 MongoDB面试题 Spring面试题 Spring Boot面试题 Spring Cloud面试题...
Netty 是一个高性能、异步事件驱动的 NIO 框架,基于 JAVA NIO 提供的 API 实现。它提供了对 TCP、UDP 和文件传输的支持,作为一个异步 NIO 框架,Netty 的所有 IO 操作都是异步非阻塞 的,通过 Future-Listener ...
Java NIO通信框架在电信领域的实践.docx java.png javaconcurrencyinpractice.pdf JavaEE学习笔记.pdf java_Java_学习笔记.pdf Java_Performance.pdf java代码效率优化.docx Java内存模型的历史变迁.docx Java在游戏...
Java NIO通信框架在电信领域的实践.docx java.png javaconcurrencyinpractice.pdf JavaEE学习笔记.pdf java_Java_学习笔记.pdf Java_Performance.pdf java代码效率优化.docx Java内存模型的历史变迁.docx Java在游戏...
Tcp服务端与客户端的JAVA实例源代码,一个简单的Java TCP服务器端程序,别外还有一个客户端的程序,两者互相配合可以开发出超多的网络程序,这是最基础的部分。 递归遍历矩阵 1个目标文件,简单! 多人聊天室 3...
编写一个java应用程序,将一个包含多个子目录和文件的目录复制到另外一个指定的目录下。 实验要求 1)欲复制的目录中包含的文件数和子目录层次未知,必须在程序执行时获得这些信息。 2)显示欲复制的目录的...
五、 封装(面向对象特征之一)★★★★ 23 六、 继承(面向对象特征之一)★★★★ 25 七、 接口(面向对象特征之一)★★★★ 28 八、 多态(面向对象特征之一)★★★★ 30 九、 java.lang.Object 31 十、 异常★...
通往架构师之路:你必须要掌握的JVM特性 一次学习终身受用-如何正确使用设计模式写出优雅的代码 年薪60万大咖深入浅出带你玩转大型互联网企业DevOps利器-Docker 架构知识透析:深入了解高并发通信模型NIO 除了上面...
Tcp服务端与客户端的JAVA实例源代码,一个简单的Java TCP服务器端程序,别外还有一个客户端的程序,两者互相配合可以开发出超多的网络程序,这是最基础的部分。 递归遍历矩阵 1个目标文件,简单! 多人聊天室 3...
搭建一个java的开发环境.mp4 │ Java面试题04.java中int占几个字节.mp4 │ Java面试题05.java面向对象的特征.mp4 │ Java面试题06.装箱和拆箱.mp4 │ Java面试题07.==和equals的区别.mp4 │ Java面试题08.String.mp4...
905.4-2014协议,是交通运输部公路科学研究院起草定制的一个协议标准,它也是基于TCP之上的一个应用层传输协议。 第2章,介绍在Socket编程过程中一些基础知识,让大家建立起对这块知识内容的一个整体轮廓; 第3章,...
3.I/O,Socket编程,首先要熟悉Java中Socket编程,以及I/O包,再深入下去就是JavaNIO,再深入下去是操作系统底层的Socket实现,了解Windows和Linux中是怎么实现socket的,如果你想学习Java可以来这个群,首先是五三二...
面试高频算法、akka、多线程、NIO、Netty、SpringBoot...综上所述,Java凭借其强大的特性和广泛的适用范围,在企业级应用、互联网服务、移动开发等领域均扮演着举足轻重的角色,是现代软件开发不可或缺的重要工具之一。