netty和nio的比较:
http://news.cnblogs.com/n/205413/
一:首先是Java IO:
Server:
package com.tch.test.chat.io; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicInteger; public class Server { private static AtomicInteger counter = new AtomicInteger(0); private static Map<Integer, PrintWriter> clients = new ConcurrentHashMap<>(); private static ExecutorService pool = Executors.newCachedThreadPool(); public static void main(String[] args) throws Throwable { ServerSocket serverSocket = new ServerSocket(8888); try { while(true){ Socket socket = serverSocket.accept(); System.out.println("a client connected ..."); pool.execute(new ClientSocketHandler(socket)); } } finally{ serverSocket.close(); } } private static class ClientSocketHandler implements Runnable{ private Socket socket; private Integer id; public ClientSocketHandler(Socket socket){ this.socket = socket; id = counter.incrementAndGet(); } @Override public void run() { try { BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); PrintWriter out = new PrintWriter(socket.getOutputStream()); clients.put(id, out); System.out.println("client num:" + clients.size()); String msg = null; while((msg = in.readLine()) != null){ System.out.println("receive msg '" + msg + "' from client-" + id); sendBack2Client("cllient-" + id + " said : " + msg); out.flush(); } } catch (IOException e) { e.printStackTrace(); } } } private static void sendBack2Client(String msg){ for(PrintWriter client : clients.values()){ client.println(msg); client.flush(); } } }
Client:
package com.tch.test.chat.io; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.Socket; public class Client { public static void main(String[] args) throws Throwable { Socket socket = new Socket("localhost", 8888); try { BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); PrintWriter out = new PrintWriter(socket.getOutputStream()); new Thread(new ServerResponseHandler(in)).start(); BufferedReader userInput = new BufferedReader(new InputStreamReader(System.in)); String msg = null; while((msg = userInput.readLine()) != null){ out.println(msg); out.flush(); } } finally{ socket.close(); } } private static class ServerResponseHandler implements Runnable{ BufferedReader in; public ServerResponseHandler(BufferedReader in){ this.in = in; } @Override public void run() { try { String msg = null; while((msg = in.readLine()) != null){ System.out.println(msg); } } catch (IOException e) { e.printStackTrace(); } } } }
二:使用Java NIO:
Server:
package com.tch.test.chat.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.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Set; public class NioServer { private Set<SelectionKey> selectionKeys = null; private Iterator<SelectionKey> iterator = null; private Iterator<SocketChannel> iterator2 = null; private List<SocketChannel> clients = new ArrayList<SocketChannel>(); private static Selector selector; static{ try { selector = Selector.open(); } catch (IOException e) { e.printStackTrace(); } } public static void main(String[] args) throws Exception { new NioServer().start(); } private void start() throws Exception{ initSeverSocketChannel(); while(true){ int ready = selector.select(); if(ready > 0){ selectionKeys = selector.selectedKeys(); iterator = selectionKeys.iterator(); while(iterator.hasNext()){ SelectionKey selectionKey = iterator.next(); if(selectionKey.isAcceptable()){ acceptClient(selectionKey); }else if(selectionKey.isReadable()){ readMsg(selectionKey); } iterator.remove(); } } } } private void initSeverSocketChannel() throws Exception{ ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); serverSocketChannel.bind(new InetSocketAddress(7878)); serverSocketChannel.configureBlocking(false); serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); } private void acceptClient(SelectionKey selectionKey) throws Exception{ ServerSocketChannel serverSocketChannel = (ServerSocketChannel)selectionKey.channel(); SocketChannel socketChannel = serverSocketChannel.accept(); socketChannel.configureBlocking(false); socketChannel.register(selector, SelectionKey.OP_READ); clients.add(socketChannel); System.out.println("a client connected ..."); } private void readMsg(SelectionKey selectionKey) throws Exception{ ByteBuffer buffer = ByteBuffer.allocate(1024); SocketChannel socketChannel = (SocketChannel)selectionKey.channel(); buffer.clear(); socketChannel.read(buffer); buffer.flip(); iterator2 = clients.iterator(); SocketChannel socketChannel2 = null; while(iterator2.hasNext()){ socketChannel2 = iterator2.next(); while(buffer.hasRemaining()){ socketChannel2.write(buffer); } buffer.rewind(); } } }
Client:
package com.tch.test.chat.nio; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; 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.SocketChannel; import java.util.Iterator; import java.util.Set; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JTextArea; import javax.swing.JTextField; public class NioClient extends JFrame{ private static final long serialVersionUID = 1L; private JTextArea area = new JTextArea(); private JTextField textField = new JTextField(); private JButton button = new JButton("Send Message"); private static Selector selector; static{ try { selector = Selector.open(); } catch (IOException e) { e.printStackTrace(); } } public static void main(String[] args) throws Exception { NioClient client = new NioClient(); client.start(); } private void start() throws Exception{ initFrame(); initSocketChannel(); while(true){ int ready = selector.select(); if(ready > 0){ Set<SelectionKey> selectionKeys = selector.selectedKeys(); Iterator<SelectionKey> iterator = selectionKeys.iterator(); while(iterator.hasNext()){ SelectionKey selectionKey = iterator.next(); if(selectionKey.isReadable()){ readMsg(selectionKey); } iterator.remove(); } } } } private void readMsg(SelectionKey selectionKey) throws Exception{ ByteBuffer buffer = ByteBuffer.allocate(1024); SocketChannel socketChannel = (SocketChannel)selectionKey.channel(); socketChannel.read(buffer); buffer.flip(); area.setText(area.getText().trim()+"\n"+new String(buffer.array(),0,buffer.limit(),"utf-8")); buffer.clear(); } private void initFrame(){ setBounds(200, 200, 300, 400); setLayout(new GridLayout(3, 1)); add(area); add(textField); add(button); setDefaultCloseOperation(EXIT_ON_CLOSE); setVisible(true); } private void initSocketChannel() throws Exception{ SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress("localhost", 7878)); socketChannel.configureBlocking(false); socketChannel.register(selector, SelectionKey.OP_READ); button.addActionListener(new MyActionListener(socketChannel)); } private class MyActionListener implements ActionListener{ private SocketChannel socketChannel; public MyActionListener(SocketChannel socketChannel){ this.socketChannel = socketChannel; } @Override public void actionPerformed(ActionEvent event) { try { ByteBuffer buffer = ByteBuffer.allocate(1024); String message = textField.getText(); if(message == null || message.trim().isEmpty()){ System.out.println("empty message"); return; } textField.setText(""); buffer.put(message.getBytes("utf-8")); buffer.flip(); while(buffer.hasRemaining()){ socketChannel.write(buffer); } buffer.clear(); } catch (Exception e) { e.printStackTrace(); } } } }
三:最后是使用netty(参考jar包里面example里面的例子):
pom.xml添加依赖:
<dependency> <groupId>io.netty</groupId> <artifactId>netty-all</artifactId> <version>4.0.36.Final</version> </dependency>
Server:
/* * Copyright 2012 The Netty Project * * The Netty Project licenses this file to you under the Apache License, * version 2.0 (the "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. */ package com.tch.test.chat.netty; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.example.telnet.TelnetServer; import io.netty.handler.logging.LogLevel; import io.netty.handler.logging.LoggingHandler; /** * Simple SSL chat server modified from {@link TelnetServer}. */ public final class NettyServer { private static final int PORT = 8992; public static void main(String[] args) throws Exception { EventLoopGroup bossGroup = new NioEventLoopGroup(1); EventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerBootstrap b = new ServerBootstrap(); b.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .handler(new LoggingHandler(LogLevel.INFO)) .childHandler(new MyServerChannelInitializer()); b.bind(PORT).sync().channel().closeFuture().sync(); } finally { bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } } }
/* * Copyright 2012 The Netty Project * * The Netty Project licenses this file to you under the Apache License, * version 2.0 (the "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. */ package com.tch.test.chat.netty; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelPipeline; import io.netty.channel.socket.SocketChannel; import io.netty.handler.codec.DelimiterBasedFrameDecoder; import io.netty.handler.codec.Delimiters; import io.netty.handler.codec.string.StringDecoder; import io.netty.handler.codec.string.StringEncoder; /** * Creates a newly configured {@link ChannelPipeline} for a new channel. */ public class MyServerChannelInitializer extends ChannelInitializer<SocketChannel> { @Override public void initChannel(SocketChannel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); // On top of the SSL handler, add the text line codec. pipeline.addLast(new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter())); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); // and then business logic. pipeline.addLast(new MyServerHandler()); } }
/* * Copyright 2012 The Netty Project * * The Netty Project licenses this file to you under the Apache License, * version 2.0 (the "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. */ package com.tch.test.chat.netty; import io.netty.channel.Channel; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; import java.net.UnknownHostException; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; /** * Handles a server-side channel. */ public class MyServerHandler extends SimpleChannelInboundHandler<String> { private static AtomicInteger counter = new AtomicInteger(0); private static Map<Channel, Integer> channels = new ConcurrentHashMap<Channel, Integer>(); @Override public void channelActive(final ChannelHandlerContext ctx) throws UnknownHostException { Integer channelNum = counter.incrementAndGet(); channels.put(ctx.channel(), channelNum); ctx.writeAndFlush("Hello user-" + channelNum + "\r\n"); } @Override public void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception { // Send the received message to all channels but the current one. for (Map.Entry<Channel, Integer> entry : channels.entrySet()) { Channel c = entry.getKey(); if (c != ctx.channel()) { c.writeAndFlush("user-" + channels.get(ctx.channel()) + " said: " + msg + '\n'); } else { c.writeAndFlush("[you] said: " + msg + '\n'); } } // Close the connection if the client has sent 'bye'. if ("bye".equals(msg.toLowerCase())) { ctx.close(); } } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { cause.printStackTrace(); ctx.close(); } }
Client:
/* * Copyright 2012 The Netty Project * * The Netty Project licenses this file to you under the Apache License, * version 2.0 (the "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. */ package com.tch.test.chat.netty; import io.netty.bootstrap.Bootstrap; import io.netty.channel.Channel; import io.netty.channel.ChannelFuture; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioSocketChannel; import io.netty.example.telnet.TelnetClient; import java.io.BufferedReader; import java.io.InputStreamReader; /** * Simple SSL chat client modified from {@link TelnetClient}. */ public final class NettyClient { private static final String HOST = "127.0.0.1"; private static final int PORT = 8992; public static void main(String[] args) throws Exception { EventLoopGroup group = new NioEventLoopGroup(); try { Bootstrap b = new Bootstrap(); b.group(group) .channel(NioSocketChannel.class) .handler(new MyClientChannelInitializer()); // Start the connection attempt. Channel ch = b.connect(HOST, PORT).sync().channel(); // Read commands from the stdin. ChannelFuture lastWriteFuture = null; BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); for (;;) { String line = in.readLine(); if (line == null) { break; } // Sends the received line to the server. lastWriteFuture = ch.writeAndFlush(line + "\r\n"); // If user typed the 'bye' command, wait until the server closes // the connection. if ("bye".equals(line.toLowerCase())) { ch.closeFuture().sync(); break; } } // Wait until all messages are flushed before closing the channel. if (lastWriteFuture != null) { lastWriteFuture.sync(); } } finally { // The connection is closed automatically on shutdown. group.shutdownGracefully(); } } }
/* * Copyright 2012 The Netty Project * * The Netty Project licenses this file to you under the Apache License, * version 2.0 (the "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. */ package com.tch.test.chat.netty; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelPipeline; import io.netty.channel.socket.SocketChannel; import io.netty.handler.codec.DelimiterBasedFrameDecoder; import io.netty.handler.codec.Delimiters; import io.netty.handler.codec.string.StringDecoder; import io.netty.handler.codec.string.StringEncoder; /** * Creates a newly configured {@link ChannelPipeline} for a new channel. */ public class MyClientChannelInitializer extends ChannelInitializer<SocketChannel> { @Override public void initChannel(SocketChannel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); // On top of the SSL handler, add the text line codec. pipeline.addLast(new DelimiterBasedFrameDecoder(8192, Delimiters.lineDelimiter())); pipeline.addLast(new StringDecoder()); pipeline.addLast(new StringEncoder()); // and then business logic. pipeline.addLast(new MyClientHandler()); } }
/* * Copyright 2012 The Netty Project * * The Netty Project licenses this file to you under the Apache License, * version 2.0 (the "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. */ package com.tch.test.chat.netty; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; /** * Handles a client-side channel. */ public class MyClientHandler extends SimpleChannelInboundHandler<String> { @Override public void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception { System.out.println(msg); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { cause.printStackTrace(); ctx.close(); } }
OK,以上就是不同的方式实现聊天。
相关推荐
Java NIO (Non-blocking Input/Output) 是Java平台中用于高效处理I/O操作的一种机制,它与传统的IO模型( Blocking I/O)相比,提供了更高级别的抽象,允许应用程序以非阻塞的方式读写数据,提高了并发性能。Netty是...
Java NIO(New IO)框架是Java平台中用于处理I/O操作的一种非阻塞I/O模型,相较于传统的IO模型,NIO提供了更高性能和更灵活的编程方式。Netty是基于Java NIO构建的一个高性能、异步事件驱动的网络应用程序框架,它极...
- **高性能**:Netty利用NIO(非阻塞IO)技术实现了高吞吐量和低延迟。 - **灵活**:提供了一种灵活的API来处理各种网络协议。 - **易于使用**:具有清晰的文档和广泛的社区支持。 - **跨平台**:可以在任何支持Java...
Java IO、NIO和Netty是Java平台中用于处理输入/输出操作的重要组件,而多线程并发则是提升程序性能和响应能力的关键技术。在这个压缩包"基于JAVA IO, NIO, Netty, 多线程并发实战源码.zip"中,我们可以期待找到一些...
Java NIO(New IO)是Java 1.4版本引入的一种新的IO API,用来替代标准的Java IO API。NIO提供了非阻塞的I/O操作,可以提高在处理多个连接时的性能。Netty是一个高性能、异步事件驱动的网络应用框架,用于快速开发可...
本篇文章将简单介绍 Netty 以及其与 Java IO 和 NIO 的关系。 首先,Java IO(Input/Output)是Java标准库提供的基本输入输出操作。IO 流模型基于阻塞IO,即当数据不可读或写入时,程序会暂停等待。这种方式在处理...
Netty和Socket.IO是两种常用于构建实时通信系统的框架,它们在在线聊天程序、客服模块以及广告推送等应用场景中有着广泛的应用。让我们深入探讨这两个技术及其在构建在线聊天程序中的运用。 **Netty** Netty是由...
Java异步NIO框架Netty实现高性能高并发无标题笔记 1. 背景 1.1. 惊人的性能数据 最近一个圈内朋友通过私信告诉我,通过使用Netty4 + Thrift压缩二进制编解码技术,他们实现了10W TPS(1K的复杂POJO对象)的跨 节点...
Apache Mina是一个轻量级的网络通信框架,它基于NIO构建,提供了一种简单的方式来编写高性能、高可用性的网络应用程序。Mina支持多种协议,如TCP、UDP、SSL/TLS等,并提供事件驱动的API,使得开发者可以专注于业务...
### Netty源码剖析与NIO及Netty5各种RPC架构实战演练三部曲知识点解析 #### 一、Netty概述 Netty是一款基于Java NIO的高性能服务器端编程框架,用于快速开发可维护的网络应用程序。它简化了网络编程的复杂性,使...
**NIO(非阻塞I/O)与Netty编程**是现代Java网络应用开发中的重要技术,它们在处理高并发、低延迟的网络通信场景中起着关键作用。本讲义详细介绍了这两种技术,旨在帮助开发者更好地理解和运用它们。 ### 一、BIO...
Netty是一个开源的Java框架,专门用于构建高性能、高可靠性的网络应用,如服务器和客户端。这个"Netty框架 jar包"很可能包含了Netty 4.1.6版本的库文件,使得开发者能够轻松地在自己的项目中集成Netty的功能。 ...
本项目是一个基于Spring Boot、Spring MVC、MyBatis和Netty的简单即时通讯聊天系统实现。这个系统的设计和实现涵盖了多个关键的Java技术栈,包括Web开发、持久化框架和网络通信,对于学习和理解现代Java后端架构具有...
Java NIO(New Input/Output)是Java标准库提供的一种I/O模型,它与传统的 Blocking I/O(IO)相比,提供了更加高效的数据传输方式。在Java NIO中,"新"主要体现在非阻塞和多路复用这两个特性上,这使得NIO更适合于...
Java NIO(New IO)是一种基于通道(Channel)和缓冲区(Buffer)的I/O操作方法。它提供了与传统IO相同的接口,但是提供了非阻塞版本的IO操作。NIO的设计目标是通过使用较少的系统资源和高效的IO操作,来处理大量的...
Java.nio,全称为Java Non-blocking Input/Output,是Java平台从1.4版本开始引入的一套全新的I/O API,旨在替代传统的Java.io流API。它提供了更高效、更灵活的I/O操作方式,特别是在处理大量并发连接时,性能显著...