传统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的区别的更多相关文章

  1. Java NIO:IO与NIO的区别 -阿里面试题

    一.概念 NIO即New IO,这个库是在JDK1.4中才引入的.NIO和IO有相同的作用和目的,但实现方式不同,NIO主要用到的是块,所以NIO的效率要比IO高很多.在Java API中提供了两套N ...

  2. 传统IO与NIO区别二

    nio是new io的简称,从jdk1.4就被引入了.现在的jdk已经到了1.6了,可以说不是什么新东西了.但其中的一些思想值得我来研究.这两天,我研究了下其中的套接字部分,有一些心得,在此分享.  ...

  3. 传统IO与NIO的比较

    本文并非Java.io或Java.nio的使用手册,也不是如何使用Java.io与Java.nio的技术文档.这里只是尝试比较这两个包,用最简单的方式突出它们的区别和各自的特性.Java.nio提出了 ...

  4. java面试题之----IO与NIO的区别

    JAVA NIO vs IO 当我们学习了Java NIO和IO后,我们很快就会思考一个问题: 什么时候应该使用IO,什么时候我应该使用NIO 在下文中我会尝试用例子阐述java NIO 和IO的区别 ...

  5. 面试题思考:IO 和 NIO的区别,NIO优点

    面试时答: IO是面向流的,NIO是面向缓冲区的 Java IO面向流意味着每次从流中读一个或多个字节,直至读取所有字节,它们没有被缓存在任何地方: NIO则能前后移动流中的数据,因为是面向缓冲区的 ...

  6. 传统IO与NIO(channel-to-channel)文件拷贝的探索与性能比对

    Channel-to-channel传输是可以极其快速的,特别是在底层操作系统提供本地支持的时候.某些操作系统可以不必通过用户空间传递数据而进行直接的数据传输.对于大量的数据传输,这会是一个巨大的帮助 ...

  7. java的nio之:java的nio系列教程之java的io和nio的区别

    当学习了Java NIO和IO的API后,一个问题马上涌入脑海: 我应该何时使用IO,何时使用NIO呢?在本文中,我会尽量清晰地解析Java NIO和IO的差异.它们的使用场景,以及它们如何影响您的代 ...

  8. Java NIO:IO与NIO的区别

    一.概念 NIO即New IO,这个库是在JDK1.4中才引入的.NIO和IO有相同的作用和目的,但实现方式不同,NIO主要用到的是块,所以NIO的效率要比IO高很多.在Java API中提供了两套N ...

  9. 【NIO】IO与NIO的区别

    一.概念 NIO即New IO,这个库是在JDK1.4中才引入的.NIO和IO有相同的作用和目的,但实现方式不同,NIO主要用到的是块,所以NIO的效率要比IO高很多.在Java API中提供了两套N ...

随机推荐

  1. android webview css z-index属性无效

    在做android的web页面嵌入的时候,当使用css的z-index设置重叠div失败: 查询google说设置 -webkit-transform:translateZ(0) canvas{ -w ...

  2. Docker入门与应用系列(六)Docker私有与公共镜像仓库

    1.搭建私有镜像仓库 Docker Hub作为Docker默认官方公共镜像:如果想搭建自己的私有镜像仓库,官方提供registry镜像,使搭建私有仓库非常简单 1.1下载registry镜像并启动 d ...

  3. 搭建一个SSM框架

    刚好学完springMVC,mybatis简单的组合,总结一下 1.创建一个maven项目,引入jar包 一共这么多,除了oracle jar包是我手动添加到lib里,其他都是通过pom.xml引入的 ...

  4. iOS开发之 -- oc和swift下输出乘法口诀表

    闲来无事,写着玩: oc: //乘法口诀表输出 ; i<=; i++) { ; j<=i; j++) { NSLog(@"%dx%d=%d\n",i,j,i*j); } ...

  5. Redis 连接失败redis Can't init enough connections amount!

    Can't init enough connections amount! Only 0 from 10 were initialized. Server: IP:6379 无法初始化足够的连接数量! ...

  6. 《基础知识》hashCode与equals的区别与联系

    一.equals方法的作用 1.默认情况(没有覆盖equals方法)下equals方法都是调用Object类的equals方法,而Object的equals方法主要用于判断对象的内存地址引用是不是同一 ...

  7. leetcode 326 Power of Three (python)

    原题: Given an integer, write a function to determine if it is a power of three. Follow up: Could you ...

  8. less.js

    在引入你自己的less文件的时候 <link rel="stylesheet/less" href="styles/site.less"> 之后再引 ...

  9. SetForegroundWindow以及 如何将一个某个窗口提到最顶层(转)

    http://hi.baidu.com/gookings/item/2b7912ca8d5b3625a0b50aa2 SetForegroundWindow 函数功能:该函数将创建指定窗口的线程设置到 ...

  10. python中 将字符串和字典的相互转换

    1.首先引入json模块 # 引入json模块 import json 2.转换 #JSON到字典转化: dictinfo = json.loads(json_str) # 输出dict类型 字典到J ...