MINA、Netty、Twisted为什么放在一起学习?首先,不妨先分别看一下它们官方网站对其的介绍:
MINA:
Apache MINA is a network application framework which helps users develop high performance and high scalability network applications easily. It provides an abstract event-driven asynchronous API over various transports such as TCP/IP and UDP/IP via Java NIO.
Netty:
Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients.
Twisted:
Twisted is an event-driven networking engine written in Python and licensed under the open source MIT license.
(Twisted官网的文案不专业啊,居然不写asynchronous)
从上面简短的介绍中,就可以发现它们的共同特点:event-driven以及asynchronous。它们都是事件驱动、异步的网络编程框架。由此可见,它们之间的共同点还是很明显的。所以我这里将这三个框架放在一起,实现相同的功能,不但可以用少量的精力学三样东西,而且还可以对它们之间进行各方面的对比。
其中MINA和Netty是基于Java语言的,而Twisted是Python语言的。不过语言不是重点,重点的是理念。
使用传统的BIO(Blocking IO/阻塞IO)进行网络编程时,进行网络IO读写时都会阻塞当前线程,如果实现一个TCP服务器,都需要对每个客户端连接开启一个线程,而很多线程可能都在傻傻的阻塞住等待读写数据,系统资源消耗大。
而NIO(Non-Blocking IO/非阻塞IO)或AIO(Asynchronous IO/异步IO)则是通过IO多路复用技术实现,不需要为每个连接创建一个线程,其底层实现是通过操作系统的一些特性如select、poll、 epoll、iocp等。这三个网络框架都是基于此实现。
下面分别用这三个框架实现一个最简单的TCP服务器。当接收到客户端发过来的字符串后,向客户端回写一个字符串作为响应。
Mina:
public class TcpServer { public static void main(String[] args) throws IOException { IoAcceptor acceptor = new NioSocketAcceptor(); acceptor.setHandler(new TcpServerHandle()); acceptor.bind(new InetSocketAddress(8080)); } } class TcpServerHandle extends IoHandlerAdapter { @Override public void exceptionCaught(IoSession session, Throwable cause) throws Exception { cause.printStackTrace(); } // 接收到新的数据 @Override public void messageReceived(IoSession session, Object message) throws Exception { // 接收客户端的数据 IoBuffer ioBuffer = (IoBuffer) message; byte[] byteArray = new byte[ioBuffer.limit()]; ioBuffer.get(byteArray, 0, ioBuffer.limit()); System.out.println("messageReceived:" + new String(byteArray, "UTF-8")); // 发送到客户端 byte[] responseByteArray = "你好".getBytes("UTF-8"); IoBuffer responseIoBuffer = IoBuffer.allocate(responseByteArray.length); responseIoBuffer.put(responseByteArray); responseIoBuffer.flip(); session.write(responseIoBuffer); } @Override public void sessionCreated(IoSession session) throws Exception { System.out.println("sessionCreated"); } @Override public void sessionClosed(IoSession session) throws Exception { System.out.println("sessionClosed"); } }
Netty:
public class TcpServer { public static void main(String[] args) throws InterruptedException { EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerBootstrap b = new ServerBootstrap(); b.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .childHandler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch) throws Exception { ch.pipeline().addLast(new TcpServerHandler()); } }); ChannelFuture f = b.bind(8080).sync(); f.channel().closeFuture().sync(); } finally { workerGroup.shutdownGracefully(); bossGroup.shutdownGracefully(); } } } class TcpServerHandler extends ChannelInboundHandlerAdapter { // 接收到新的数据 @Override public void channelRead(ChannelHandlerContext ctx, Object msg) throws UnsupportedEncodingException { try { // 接收客户端的数据 ByteBuf in = (ByteBuf) msg; System.out.println("channelRead:" + in.toString(CharsetUtil.UTF_8)); // 发送到客户端 byte[] responseByteArray = "你好".getBytes("UTF-8"); ByteBuf out = ctx.alloc().buffer(responseByteArray.length); out.writeBytes(responseByteArray); ctx.writeAndFlush(out); } finally { ReferenceCountUtil.release(msg); } } @Override public void channelActive(ChannelHandlerContext ctx) { System.out.println("channelActive"); } @Override public void channelInactive(ChannelHandlerContext ctx){ System.out.println("channelInactive"); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { cause.printStackTrace(); ctx.close(); } }
Twisted:
# -*- coding:utf-8 –*- from twisted.internet.protocol import Protocol from twisted.internet.protocol import Factory from twisted.internet import reactor class TcpServerHandle(Protocol): # 新的连接建立 def connectionMade(self): print 'connectionMade' # 连接断开 def connectionLost(self, reason): print 'connectionLost' # 接收到新数据 def dataReceived(self, data): print 'dataReceived', data self.transport.write('你好') factory = Factory() factory.protocol = TcpServerHandle reactor.listenTCP(8080, factory) reactor.run()
上面的代码可以看出,这三个框架实现的TCP服务器,在连接建立、接收到客户端传来的数据、连接关闭时,都会触发某个事件。例如接收到客户端传来的 数据时,MINA会触发事件调用messageReceived,Netty会调用channelRead,Twisted会调用 dataReceived。编写代码时,只需要继承一个类并重写响应的方法即可。这就是event-driven事件驱动。
下面是Java写的一个TCP客户端用作测试,客户端没有使用这三个框架,也没有使用NIO,只是一个普通的BIO的TCP客户端。
TCP在建立连接到关闭连接的过程中,可以多次进行发送和接收数据。下面的客户端发送了两个字符串到服务器并两次获取服务器回应的数据,之间通过Thread.sleep(5000)间隔5秒。
public class TcpClient { public static void main(String[] args) throws IOException, InterruptedException { Socket socket = null; OutputStream out = null; InputStream in = null; try{ socket = new Socket("localhost", 8080); out = socket.getOutputStream(); in = socket.getInputStream(); // 请求服务器 out.write("第一次请求".getBytes("UTF-8")); out.flush(); // 获取服务器响应,输出 byte[] byteArray = new byte[1024]; int length = in.read(byteArray); System.out.println(new String(byteArray, 0, length, "UTF-8")); Thread.sleep(5000); // 再次请求服务器 out.write("第二次请求".getBytes("UTF-8")); out.flush(); // 再次获取服务器响应,输出 byteArray = new byte[1024]; length = in.read(byteArray); System.out.println(new String(byteArray, 0, length, "UTF-8")); } finally { // 关闭连接 in.close(); out.close(); socket.close(); } } }
用客户端分别测试上面三个TCP服务器:
MINA服务器输出结果:
sessionCreated
messageReceived:第一次请求
messageReceived:第二次请求
sessionClosed
Netty服务器输出结果:
channelActive
channelRead:第一次请求
channelRead:第二次请求
channelInactive
Twisted服务器输出结果:
connectionMade
dataReceived: 第一次请求
dataReceived: 第二次请求
connectionLost
相关推荐
#### 二、MiNA框架简介 MiNA框架是一种基于Java的高性能网络应用程序开发框架,它简化了网络编程中的复杂性,使开发者能够更加专注于业务逻辑而不是底层网络细节。MiNA提供了一套强大的API来处理各种网络通信任务,...
总结起来,基于MINA的TLS/SSL NIO Socket实现涉及到的主要步骤包括: 1. 创建SSLContext并配置证书、密钥和协议。 2. 创建SSLEngine,并根据应用角色设置工作模式。 3. 在MINA的IoFilterChain中添加SSLFilter。 4. ...
总结来说,这个压缩包提供了全面的MINA开发资源,包括必要的库文件和详细的文档,对于想要学习和使用MINA进行网络应用开发的人员来说非常有价值。通过深入阅读手册,理解和实践提供的示例,开发者可以快速掌握MINA的...
编码是将对象转换为二进制数据包,进而形成连续的二进制数据流;解码则是将数据流中的数据包拆分并还原为原始对象。Mina通过其内置的协议编解码器,为这些操作提供了高度封装,大大提高了代码的复用性和维护性。 ##...
标题“Java学习之IO总结及mina和netty”涉及到的知识点包括: 1. **Java基础IO**: - 字节流(InputStream和OutputStream):用于处理二进制数据,如图片、音频等。 - 字符流(Reader和Writer):处理文本数据,...
总结来说,Mina小Demo是一款结合了Mina的强大网络通信能力与Swing易用界面的示例应用,对于Java开发者来说,无论是学习网络编程还是GUI设计,都是一个很好的实践案例。通过深入研究其源码,我们可以更深入地理解Java...
《Mina中转服务详解与应用》 ...总结,Mina中转服务是构建高性能、可扩展网络应用的关键组件。通过理解其工作原理和使用方法,开发者可以有效地利用Minaclient来设计和实现复杂的网络通信解决方案。
#### 二、Mina架构与核心组件 Mina的核心组件主要包括`IoService`、`IoProcessor`、`IoFilter`和`IoHandler`。 1. **IoService**:该接口负责管理网络连接,如监听新连接的建立或断开。它拥有一个Selector来监控...
#### 二、Mina功能与支持 Mina不仅支持基于Java NIO的TCP/UDP应用程序开发,还在最新的预览版中提供了对串口通信的支持。这一特性极大地扩展了Mina的应用场景,使其不仅仅局限于传统的网络应用程序,还适用于嵌入式...
总结,《Mina官方教程_中文版》提供了全面且深入的指导,适合初学者和有经验的开发者了解和掌握Mina框架,提升网络编程能力。通过学习这份教程,读者将能够运用Mina构建高效的网络应用程序,满足各种业务需求。
总结起来,Apache Mina和Flex AS3.0的交互涉及到网络通信、数据交换、服务端和客户端API的使用、事件驱动编程以及安全性与性能优化等多个方面。这种交互方式为开发高效、功能丰富的跨平台应用程序提供了可能,使...
MINA2是其第二个主要版本,提供了一套全面的API,使得开发者能够更方便地开发出稳定、高效的网络服务。 本文将围绕MINA2推送Demo客户端进行深入解析,以"echo_client_udp"为例,讲解如何利用MINA2实现一个简单的UDP...
#### 二、Mina基础概念详解 **IoService接口** IoService接口是Mina中的关键组件,用于管理网络连接和数据传输。其主要职责包括: - 开启或关闭网络连接 - 注册或取消注册IoHandler - 启动或停止IoAcceptor和...
总结,Mina服务器实例为我们提供了一种高效、灵活的方式来构建网络应用,尤其在前后台推送和Android Web应用中,它的强大功能和易用性得到了充分展示。通过理解Mina的基本概念和工作原理,我们可以更好地利用这个...
总结,通过本案例,我们可以了解如何利用Apache Mina框架与Socket技术实现文件的双向传输。这个过程涉及网络通信基础、Mina的核心组件以及文件传输的具体策略。通过深入学习和实践,开发者可以更好地理解和应用网络...
**二、Mina基础** **2.1 IoService接口** IoService是Mina的核心接口,它代表了网络服务,可以是服务器(Acceptor)也可以是客户端(Connector)。IoService提供了一系列方法来管理和控制网络连接。 **2.1.1 类...
总结起来,Apache MINA是一个强大的网络应用框架,提供异步事件驱动、协议无关和高度可扩展的特性,适用于各种网络服务的开发。通过下载并研究"apache-mina-2.1.3所有jar和源文件",开发者不仅可以快速构建高效的...
二、Mina的事件驱动模型 Mina采用事件驱动模型,当网络连接、数据读写等事件发生时,会触发相应的处理器。这种模型使得Mina具有很好的并发性能,可以高效地处理大量并发连接。 三、Mina的过滤器机制 过滤器是Mina...