netty1---传统IO和NIO的区别
传统IO;
- package OIO;
- import java.io.IOException;
- import java.io.InputStream;
- import java.net.ServerSocket;
- import java.net.Socket;
- import java.util.concurrent.ExecutorService;
- import java.util.concurrent.Executors;
- /**
- * 传统socket服务端
- */
- public class OioServer {
- @SuppressWarnings("resource")
- public static void main(String[] args) throws Exception {
- ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
- //创建socket服务,监听10101端口
- ServerSocket server=new ServerSocket(10101);
- System.out.println("服务器启动!");
- while(true){
- //阻塞
- final Socket socket = server.accept();//有一个客户端进来就向下执行,长连接的服务器。
- //用线程池可以有多个客户端连接,但是非常消耗性能
- //tomcat里面来一个请求就开一个线程,当一问一答结束,服务端主动关闭,那么这个线程就可以为其他请求服务了。
- System.out.println("来个一个新客户端!");
- newCachedThreadPool.execute(new Runnable() {
- @Override
- public void run() {
- handler(socket);
- }
- });
- }
- }
- /**
- * 读取数据
- */
- public static void handler(Socket socket){
- try {
- byte[] bytes = new byte[1024];
- InputStream inputStream = socket.getInputStream();//获取输入流
- while(true){
- //阻塞
- int read = inputStream.read(bytes);
- if(read != -1){// -1就是客户端关闭了。
- System.out.println(new String(bytes, 0, read));
- }else{
- break;
- }
- }
- } catch (Exception e) {
- e.printStackTrace();
- }finally{
- try {
- System.out.println("socket关闭");
- socket.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- }
NIO:
- package NIO;
- 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.util.Iterator;
- /**
- * NIO服务端
- */
- public class NIOServer {
- // 通道管理器
- private Selector selector;
- /**
- * 获得一个ServerSocket通道,并对该通道做一些初始化的工作
- */
- public void initServer(int port) throws IOException {
- // 获得一个ServerSocket通道
- ServerSocketChannel serverChannel = ServerSocketChannel.open();
- // 设置通道为非阻塞,只能是非阻塞的。
- serverChannel.configureBlocking(false);
- // 将该通道对应的ServerSocket绑定到port端口
- serverChannel.socket().bind(new InetSocketAddress(port));
- // 获得一个通道管理器
- this.selector = Selector.open();
- // 将通道管理器和该通道绑定,并为该通道注册SelectionKey.OP_ACCEPT事件,注册该事件后,
- // 当该事件到达时,selector.select()会返回,如果该事件没到达selector.select()会一直阻塞。
- //注册请求连接进来的key : OP_ACCEPT
- serverChannel.register(selector, SelectionKey.OP_ACCEPT);
- }
- /**
- * 采用轮询的方式监听selector上是否有需要处理的事件,如果有,则进行处理
- */
- public void listen() throws IOException {
- System.out.println("服务端启动成功!");
- // 轮询访问selector
- //客户端连接进来和发送数据的请求,都走这里,这里是死循环。
- while (true) {
- // 当注册的事件到达时,方法返回;否则,该方法会一直阻塞,
- //客户端连接进来和发送数据的请求,都走这里,阻塞
- selector.select();//select是C实现的,多路复用的实现。
- // 获得selector中选中的项的迭代器,选中的项为注册的事件
- Iterator<?> ite = this.selector.selectedKeys().iterator();
- while (ite.hasNext()) {
- SelectionKey key = (SelectionKey) ite.next();
- // 删除已选的key,以防重复处理
- ite.remove();
- handler(key);
- }
- }
- }
- /**
- * 处理请求,客户端连接进来和客户端发数据,走这里。
- */
- public void handler(SelectionKey key) throws IOException {
- // 客户端连接进来
- if (key.isAcceptable()) {
- handlerAccept(key);
- // 客户端发数据
- } else if (key.isReadable()) {
- handelerRead(key);
- }
- }
- /**
- * 处理连接请求
- */
- public void handlerAccept(SelectionKey key) throws IOException {
- ServerSocketChannel server = (ServerSocketChannel) key.channel();
- // 获得和客户端连接的通道,
- SocketChannel channel = server.accept();
- // 设置成非阻塞
- channel.configureBlocking(false);
- // 在这里可以给客户端发送信息哦
- System.out.println("新的客户端连接");
- // 在和客户端连接成功之后,为了可以接收到客户端的信息,需要给通道设置读的权限。
- //注册接收消息的key : OP_READ
- channel.register(this.selector, SelectionKey.OP_READ);
- }
- /**
- * 处理读的事件
- */
- public void handelerRead(SelectionKey key) throws IOException {
- // 服务器可读取消息:得到事件发生的Socket通道
- SocketChannel channel = (SocketChannel) key.channel();
- // 创建读取的缓冲区
- ByteBuffer buffer = ByteBuffer.allocate(1024);
- int read = channel.read(buffer);
- if(read > 0){
- byte[] data = buffer.array();
- String msg = new String(data).trim();
- System.out.println("服务端收到信息:" + msg);
- //回写数据
- ByteBuffer outBuffer = ByteBuffer.wrap("好的".getBytes());
- channel.write(outBuffer);// 将消息回送给客户端
- }else{
- System.out.println("客户端关闭");
- key.cancel();
- }
- }
- /**
- * 启动服务端测试
- */
- public static void main(String[] args) throws IOException {
- NIOServer server = new NIOServer();
- server.initServer(8000);
- server.listen();
- }
- }
- Netty入门教程
- 第一天内容 传统IO与NIO比较
- 传送IO特点
- =======================分割线==========================
- NIO的新API
- ServerSocketChannel,对应传统IO的: ServerSocket
- SocketChannel,对应传统IO的: Socket
- Selector:NIO核心的东西,负责监听ServerSocketChannel、SocketChannel。NIO是可以实现单线程为多个客户端服务的。传统IO是做不到的, 传统IO要多线程才行。
- SelectionKey:监听的事件。
- NIO的一些疑问
- 1、客户端关闭的时候会抛出异常,死循环
- 解决方案
- int read = channel.read(buffer);
- if(read > 0){
- byte[] data = buffer.array();
- String msg = new String(data).trim();
- System.out.println("服务端收到信息:" + msg);
- //回写数据
- ByteBuffer outBuffer = ByteBuffer.wrap("好的".getBytes());
- channel.write(outBuffer);// 将消息回送给客户端
- }else{
- System.out.println("客户端关闭");
- key.cancel();
- }
- 2、selector.select();阻塞,那为什么说nio是非阻塞的IO?
- selector.select()
- selector.select(1000);阻塞1秒,1秒还没有请求过来就返回了,
- selector.wakeup();也可以唤醒selector
- selector.selectNow();也可以立马返还,视频里忘了讲了,哈,这里补上
- 3、SelectionKey.OP_WRITE是代表什么意思:OP_WRITE表示底层缓冲区是否有空间(事件的触发条件),是则响应返还true,一般不注册这个事件。
netty1---传统IO和NIO的区别的更多相关文章
- Java NIO:IO与NIO的区别 -阿里面试题
一.概念 NIO即New IO,这个库是在JDK1.4中才引入的.NIO和IO有相同的作用和目的,但实现方式不同,NIO主要用到的是块,所以NIO的效率要比IO高很多.在Java API中提供了两套N ...
- 传统IO与NIO区别二
nio是new io的简称,从jdk1.4就被引入了.现在的jdk已经到了1.6了,可以说不是什么新东西了.但其中的一些思想值得我来研究.这两天,我研究了下其中的套接字部分,有一些心得,在此分享. ...
- 传统IO与NIO的比较
本文并非Java.io或Java.nio的使用手册,也不是如何使用Java.io与Java.nio的技术文档.这里只是尝试比较这两个包,用最简单的方式突出它们的区别和各自的特性.Java.nio提出了 ...
- java面试题之----IO与NIO的区别
JAVA NIO vs IO 当我们学习了Java NIO和IO后,我们很快就会思考一个问题: 什么时候应该使用IO,什么时候我应该使用NIO 在下文中我会尝试用例子阐述java NIO 和IO的区别 ...
- 面试题思考:IO 和 NIO的区别,NIO优点
面试时答: IO是面向流的,NIO是面向缓冲区的 Java IO面向流意味着每次从流中读一个或多个字节,直至读取所有字节,它们没有被缓存在任何地方: NIO则能前后移动流中的数据,因为是面向缓冲区的 ...
- 传统IO与NIO(channel-to-channel)文件拷贝的探索与性能比对
Channel-to-channel传输是可以极其快速的,特别是在底层操作系统提供本地支持的时候.某些操作系统可以不必通过用户空间传递数据而进行直接的数据传输.对于大量的数据传输,这会是一个巨大的帮助 ...
- java的nio之:java的nio系列教程之java的io和nio的区别
当学习了Java NIO和IO的API后,一个问题马上涌入脑海: 我应该何时使用IO,何时使用NIO呢?在本文中,我会尽量清晰地解析Java NIO和IO的差异.它们的使用场景,以及它们如何影响您的代 ...
- Java NIO:IO与NIO的区别
一.概念 NIO即New IO,这个库是在JDK1.4中才引入的.NIO和IO有相同的作用和目的,但实现方式不同,NIO主要用到的是块,所以NIO的效率要比IO高很多.在Java API中提供了两套N ...
- 【NIO】IO与NIO的区别
一.概念 NIO即New IO,这个库是在JDK1.4中才引入的.NIO和IO有相同的作用和目的,但实现方式不同,NIO主要用到的是块,所以NIO的效率要比IO高很多.在Java API中提供了两套N ...
随机推荐
- java.awt包提供了基本的java程序的GUI设计工具
java.awt包提供了基本的java程序的GUI设计工具.主要包括下述三个概念: 组件--Component 容器--Container 布局管理器--LayoutManager package T ...
- java拆装箱(转)
转载:http://www.cnblogs.com/dolphin0520/p/3780005.html 深入剖析Java中的装箱和拆箱 自动装箱和拆箱问题是Java中一个老生常谈的问题了,今天我们就 ...
- redhat ent6.5使用centos yum
转载自:http://blog.csdn.net/zhngjan/article/details/20843465 搜狐镜像库:mirrors.sohu.com 163镜像库:mirrors.163. ...
- library和libraryTarget使用场景组件开发
https://segmentfault.com/q/1010000004676608 https://github.com/zhengweikeng/blog/issues/10
- Cocos2d-x 3.3Bate0 ExpandedListView
之前写的ExpandedListView版本号因为版本号升级这里提供Cocos2d-x 3.3Bate0 版本号 代码下载:http://download.csdn.net/detail/qqmcy/ ...
- [.NET网格计算框架] Alchemi
Alchemi [.NET网格计算框架] 是 一个以使用简易为目的的Windows下的网格计算框架.它提供了:a)开发网格软件的编程环境 和 b)建造网格和运行网格软件的运行机制. A ...
- Django - 请求与响应、表单、中间件、上下文处理器
请求与响应篇 一.HttpRequest对象 服务器接收到http协议的请求后,会根据报文创建HttpRequest对象.视图函数的第一个参数(request)是HttpRequest对象在djang ...
- ssh框架搭建出现的问题和解决
[说明]今天尝试从头开始搭建ssh 框架, 真心是有点不太容易,可能是第一次吧,之前都是小打小闹. 一:今日完成 搭建 Spring 环境 --> 然后搭建 Hibernate 环境 --> ...
- tomcat登录账户配置
tomcat7和tomcat6的用户信息配置有些不一样,tomcat7中添加了manager=gui和admin-gui角色,配置参考如下: 再 tomcat 文件夹的conf文件夹中的 tomcat ...
- python之django直接执行sql语句
python之django直接执行sql语句 sql = 'select * from stu' info = 模型类.objects.raw(sql)