`

Netty -入门IO与NIO

 
阅读更多

1、什么是Netty

       Netty是由JBOSS提供的一个java开源框架。Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序。
       也就是说,Netty 是一个基于NIO的客户,服务器端编程框架,使用Netty 可以确保你快速和简单的开发出一个网络应用,例如实现了某种协议的客户,服务端应用。Netty相当简化和流线化了网络应用的编程开发过程,例如,TCP和UDP的socket服务开发。

2、什么是NIO

       Java NIO(New IO)是从Java 1.4版本开始引入的一个新的IO API,可以替代标准的Java IO API。也有人将NIO 称之为 Non-block I/O (非阻塞I/O),貌似这个称呼更能体现NIO与传统IO的区别。

       Java NIO提供了与标准IO不同的IO工作方式:

       ① Channels and Buffers(通道和缓冲区):标准的IO基于字节流和字符流进行操作的,而NIO是基于通道(Channel)和缓冲区(Buffer)进行操作,数据总是从通道读取到缓冲区中,或者从缓冲区写入到通道中。
       ② Asynchronous IO(异步IO):Java NIO可以让你异步的使用IO,例如:当线程从通道读取数据到缓冲区时,线程还是可以进行其他事情。当数据被写入到缓冲区时,线程可以继续处理它。从缓冲区写入通道也类似。
       ③Selectors(选择器):Java NIO引入了选择器的概念,选择器用于监听多个通道的事件(比如:连接打开,数据到达)。因此,单个的线程可以监听多个数据通道。

 

详细请参考《Java NIO 系列教程

 

 3、Netty给我们解决了什么问题

        功能强大,简化了NIO开发,Netty 是一个异步的,事件驱动的网络编程框架,使用它能够快速开发出高性能的、可维护性较强的、可扩展性较强的协议服务的服务端和客户端。

 

4、示例 标准IO

服务端

TimeServer:

 

package com.techstar.io;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * Server
 * @author mrh
 *
 */
public class TimeServer {

	
	/**
	 * 启动服务
	 * @param args
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException {
		
		int port = 8081;
		ServerSocket server = null;
		try {
			server = new ServerSocket(port);
			System.out.println("TimeServer is started .......");
			Socket socket = null;
			while(true) {
				socket = server.accept();
				new Thread(new TimeServerHandler(socket)).start();
			}
		} finally {
			if (server != null) {
				System.out.println("The TimeServer is closed .......");
				server.close();
			}
		}
		
	}
}
 TimeServerHandler
package com.techstar.io;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Date;

public class TimeServerHandler implements Runnable{

	private Socket socket;
	
	public TimeServerHandler(Socket socket) {
		super();
		this.socket = socket;
	}


	@Override
	public void run() {
		BufferedReader reader = null;
		PrintWriter writer = null;
		
		try {
			reader = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));
			writer = new PrintWriter(this.socket.getOutputStream(), true);
			
			String currentTime = null;
			String body = null;
			
			while(true) {
				body = reader.readLine();
				if (body == null) 
					break;
				System.out.println("The time server receive order:" + body);
				currentTime = "QUERY TIME ORDER".equals(body)?new Date(System.currentTimeMillis()).toString() : "BAD ORDER";
				writer.println(currentTime);
				writer.flush();
			}
		} catch (Exception e) {
			if (writer != null) {
				writer.close();
				writer = null;
			}
			
			if (reader != null) {
				try {
					reader.close();
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			}
			if (this.socket != null) {
				try {
					this.socket.close();
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
				this.socket = null;
			}
		}
		
	}

}
 

 

客户端:

package com.techstar.io;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

public class TimeClient {

	
	public static void main(String[] args) {
		int port = 8081;
		BufferedReader reader = null;
		PrintWriter writer = null;
		Socket socket = null;
		try {
			socket = new Socket("127.0.0.1", port);
			reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
			writer = new PrintWriter(socket.getOutputStream(), true);
			
			writer.println("QUERY TIME ORDER");
			writer.flush();
			System.out.println("send order to server successed!");
			String response = reader.readLine();
			System.out.println("Now is " + response);
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			if (writer != null) {
				writer.close();
				writer = null;
			}
			
			if (reader != null) {
				try {
					reader.close();
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			}
			if (socket != null) {
				try {
					socket.close();
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
				socket = null;
			}
		}
		
	}
}

 

 5、 Linux网络 I/O 模型简介

① 阻塞 I/O 模型

 最常用的 I/O 模型就是阻塞 I/O 模型, 缺省情形下, 所有文件操作都是阻塞的。如下图所示

 

 

 

优劣:简单,效率低

② 非阻塞 I/O 模型

理解了阻塞I/O,非阻塞I/O就好理解。非阻塞I/O是程序执行过程中,I/O操作不会阻塞程序的执行,也就是在I/O操作的同时,继续执行其他代码(这得益于Node的事件循环机制)。在I/O设备效率还远远低于CPU效率的时代,这种I/O模型(非阻塞I/O)为程序带来的性能上的提高是非常可观的

非阻塞IO模型

 

 优劣:效率高,复杂

③ I/O 复用模型

 让应用程序可以同时对多个I/O端口进行监控以判断其上的操作是否可以进行,达到时间复用的目的。在书上看到一个例子来解释I/O的原理,我觉得很形象,如果用监控来自10根不同地方的水管(I/O端口)是否有水流到达(即是否可读),那么需要10个人(即10个线程或10处代码)来做这件事。如果利用某种技术(比如摄像头)把这10根水管的状态情况统一传达到某一点,那么就只需要1个人在那个点进行监控就行了,而类似与select或epoll这样的多路I/O复用机制就好比是摄像头的功能,它们能够把多个I/O端口的状况反馈到同一处,比如某个特定的文件描述符上,这样应用程序只需利用对应的select()或epoll_wait()系统调用阻塞关注这一处即可。
优劣:由于I/O多路复用是在单一进程的上下文中的,因此每个逻辑流程都能访问该进程的全部地址空间,所以开销比多进程低得多;缺点是编程复杂度高

 

 

 

④ 信号驱动 I/O 模型

 让内核在描述字就绪时发送SIGIO信号通知我们。首先开启套接口的信号驱动1/O功能,sigaction系统调用安装一个信号处理函数,当内核数据包准备好时,会为该进程产生一个SIGIO信号。

 

 

 

⑤ 异步 I/O告知内核启动某个操作,并让内核在整个操作完成后(包括将数据从内核复制到用户自己的缓冲区)通知我们。与信号模型的区别就在于:信号驱动IO由内核通知我们何时可以开始下一个IO操作;异步I/O模型由内核通知我们I/O操作何时完成。

 

 

6、NIO的主要组件

① Buffer

缓冲区, 几乎每种Java数据类型都有一个

 

 

② Channel

数据就是一个通道, 网络数据通过Channel读取写入。与传统的IO不同, 它是双向的,允许同时进行读写操作。

 

③ Selector

NIO的基础,掌握Selector的熟练度,就决定了对NIO编程的熟练度。

Selector(选择器)能够检测一到多个NIO通道,并能够知晓通道是否为诸如读写事件做好准备的组件。这样,一个单独的线程可以管理多个channel,从而管理多个网络连接。

好处:

仅用单个线程来处理多个Channels的好处是,只需要更少的线程来处理通道

 

  

 

 

  • 大小: 21.6 KB
  • 大小: 26.4 KB
  • 大小: 5.9 KB
分享到:
评论

相关推荐

    NettyInAction中文版

    NettyInAction中文版,共13章,从入门到精通。Netty介绍 为什么要使用non-blocking IO(NIO) 阻塞IO(blocking IO)和非阻塞IO(non-blocking IO)对比 Java NIO的问题和在Netty中的解决方案 Netty是基于Java NIO的网络...

    IO、通信中间件Netty入门

    Netty 是由 JBOSS 提供的一个java开源框架, 是业界最流行的NIO框 架,整合了多种协议 包括FTP、SMTP、HTTP等各种二进制文本协议)的实现经验,精 心设计的框架,在多个大型商业项目中得到充分验证。

    高清Netty5.0架构剖析和源码解读

    业界主流的NIO框架介绍10 2.NIO入门10 2.1. NIO服务端10 2.2. NIO客户端13 3.Netty源码分析16 3.1. 服务端创建16 3.1.1. 服务端启动辅助类ServerBootstrap16 3.1.2. NioServerSocketChannel 的注册21 3.1.3. 新的...

    《初入JavaIO之门BIO、NIO、AIO实战练习》源码

    netty案例,netty4.1基础入门篇零《初入JavaIO之门BIO、NIO、AIO实战练习》 ...

    Netty权威指南

    基础篇:java的IO演进之路; BIO ;NIO;伪异步;NIO类库 ; 入门篇:Jetty简单应用入门;TCP粘包拆包;定位符和定长解码器; 中级篇:编解码技术和常用的序列化框架(protobuf /java/Marshalling) 高级篇:Http协议...

    Netty权威指南 第2版 高清+书签

    《Netty 权威指南(第2 版)》是异步非阻塞通信领域的...内容不仅包含Java NIO入门知识、Netty 的基础功能开发指导、编解码框架定制等,还包括私有协议栈定制和开发、Netty 核心类库源码分析,以及Netty 的架构剖析。

    Netty In Action中文版

    非常有用的入门级别资源,学习netty的不二之选,写的很好,强烈推荐

    java开源包3

    Tomcat Native 这个项目可以让 Tomcat 使用 Apache 的 apr 包来处理包括文件和网络IO操作,以提升性能。 预输入搜索 Cleo Cleo 是一个灵活的软件库用于处理一些预输入和自动完成的搜索功能,该项目是 LinkedIn 公司...

    java开源包1

    Tomcat Native 这个项目可以让 Tomcat 使用 Apache 的 apr 包来处理包括文件和网络IO操作,以提升性能。 预输入搜索 Cleo Cleo 是一个灵活的软件库用于处理一些预输入和自动完成的搜索功能,该项目是 LinkedIn 公司...

    java开源包10

    Tomcat Native 这个项目可以让 Tomcat 使用 Apache 的 apr 包来处理包括文件和网络IO操作,以提升性能。 预输入搜索 Cleo Cleo 是一个灵活的软件库用于处理一些预输入和自动完成的搜索功能,该项目是 LinkedIn 公司...

    JAVA上百实例源码以及开源项目源代码

     Java二进制IO类与文件复制操作实例,好像是一本书的例子,源代码有的是独立运行的,与同目录下的其它代码文件互不联系,这些代码面向初级、中级Java程序员。 Java访问权限控制源代码 1个目标文件 摘要:Java源码,...

    java开源包11

    Tomcat Native 这个项目可以让 Tomcat 使用 Apache 的 apr 包来处理包括文件和网络IO操作,以提升性能。 预输入搜索 Cleo Cleo 是一个灵活的软件库用于处理一些预输入和自动完成的搜索功能,该项目是 LinkedIn 公司...

    java开源包2

    Tomcat Native 这个项目可以让 Tomcat 使用 Apache 的 apr 包来处理包括文件和网络IO操作,以提升性能。 预输入搜索 Cleo Cleo 是一个灵活的软件库用于处理一些预输入和自动完成的搜索功能,该项目是 LinkedIn 公司...

    java开源包6

    Tomcat Native 这个项目可以让 Tomcat 使用 Apache 的 apr 包来处理包括文件和网络IO操作,以提升性能。 预输入搜索 Cleo Cleo 是一个灵活的软件库用于处理一些预输入和自动完成的搜索功能,该项目是 LinkedIn 公司...

    java开源包5

    Tomcat Native 这个项目可以让 Tomcat 使用 Apache 的 apr 包来处理包括文件和网络IO操作,以提升性能。 预输入搜索 Cleo Cleo 是一个灵活的软件库用于处理一些预输入和自动完成的搜索功能,该项目是 LinkedIn 公司...

    java开源包4

    Tomcat Native 这个项目可以让 Tomcat 使用 Apache 的 apr 包来处理包括文件和网络IO操作,以提升性能。 预输入搜索 Cleo Cleo 是一个灵活的软件库用于处理一些预输入和自动完成的搜索功能,该项目是 LinkedIn 公司...

    java开源包8

    Tomcat Native 这个项目可以让 Tomcat 使用 Apache 的 apr 包来处理包括文件和网络IO操作,以提升性能。 预输入搜索 Cleo Cleo 是一个灵活的软件库用于处理一些预输入和自动完成的搜索功能,该项目是 LinkedIn 公司...

    java开源包7

    Tomcat Native 这个项目可以让 Tomcat 使用 Apache 的 apr 包来处理包括文件和网络IO操作,以提升性能。 预输入搜索 Cleo Cleo 是一个灵活的软件库用于处理一些预输入和自动完成的搜索功能,该项目是 LinkedIn 公司...

    java开源包9

    Tomcat Native 这个项目可以让 Tomcat 使用 Apache 的 apr 包来处理包括文件和网络IO操作,以提升性能。 预输入搜索 Cleo Cleo 是一个灵活的软件库用于处理一些预输入和自动完成的搜索功能,该项目是 LinkedIn 公司...

Global site tag (gtag.js) - Google Analytics