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 IO, NIO, Netty, 多线程并发实战源码.zip
Java异步NIO框架Netty实现高性能高并发无标题笔记 1. 背景 1.1. 惊人的性能数据 最近一个圈内朋友通过私信告诉我,通过使用Netty4 + Thrift压缩二进制编解码技术,他们实现了10W TPS(1K的复杂POJO对象)的跨 节点...
io nio netty等
t-io是基于aio(nio2)的网络编程框架,和netty属于同类,但t-io更注重开发一线工程师的感受,提供了大量和业务相关的API。基于t-io来开发IM、TCP私有协议、RPC、游戏服务器端、推送服务、实时监控、物联网、UDP、...
Netty is a NIO client server framework which enables quick and easy development of network applications such as protocol servers and clients. It greatly simplifies and streamlines network programming ...
Netty 是一个利用 Java 的高级网络的能力,隐藏其背后的复杂性而提供一个易于使用的 API 的客户端/服务器框架。 Netty 是一个广泛使用的 Java 网络编程框架(Netty 在 2011 年获得了Duke's Choice Award,见...
远古: java.net + io java.net + iojava.net + java.iojava.net + java.iojava.net + java.iojava.net + java.iojava.net + java.io java.net + io java.net + io java.net + iojava.net + java.iojava.net + java....
Netty (netty-netty-5.0.0.Alpha2.tar.gz)是一个 NIO 客户端服务器框架,可以快速轻松地开发协议服务器和客户端等网络应用程序。它极大地简化和流线了网络编程,例如 TCP 和 UDP 套接字服务器。 “快速和简单”并...
NULL 博文链接:https://b-l-east.iteye.com/blog/1260230
Netty is a NIO client server framework which enables quick and easy development of network applications such as protocol servers and clients. It greatly simplifies and streamlines network programm ...
java 1.4起,jdk支持了NIO(NEW IO),因NIO(os nonblocking)的非阻塞式工作方式,让应用服务器可以极大的优化线程模型,相比传统的阻塞式IO线程和链路一对一的模式,NIO只需少量的线程即可处理所有的链路,这对广大的...
Netty is a NIO client server framework which enables quick and easy development of network applications such as protocol servers and clients. It greatly simplifies and streamlines network programming ...
简单来说就是java通过io流方式和外部设备进行交互。 在Java类库中,IO部分的内容是很庞大的,因为它涉及的领域很广泛:标准输入输出,文件的操作,网络上 的数据传输流,字符串流,对象流等等等。 比如程序从服务器...
Java高级编程、内有Java IO NIO,Java+netty等框架技术详解。
Netty提供了一种新的方式来开发网络应用程序,这种新的方式使它很容易使用和具有很强的扩展性。Netty的内部实现是很复杂的,但是Netty提供了简单易用的API从网络处理代码中解耦业务逻辑。Netty是完全基于NIO实现的,...
netty案例,netty4.1基础入门篇零《初入JavaIO之门BIO、NIO、AIO实战练习》 ...
80_Netty复合缓冲区详解与3种缓冲区适用场景分析 81_Netty引用计数的实现机制与自旋锁的使用技巧 82_Netty引用计数原子更新揭秘与AtomicIntegerFieldUpdater深度剖析 83_AtomicIntegerFieldUpdater实例演练与...
Netty是基于Java NIO的网络应用框架,如果你是Java网络方面的新手,那么本章将是你学习Java网络应用的开始;对于有 经验的开发者来说,学习本章内容也是很好的复习。如果你熟悉NIO和NIO2,你可以随时跳过本章直接从...
净额从原生Java的Io操作(BIO)到NIO编程,约会NIO高效并发框架——Netty,需要用到Java的基础知识(多线程,网络编程,IO,设计模式尤其是代理模式),介绍了Netty的高级架构设计和核心模块组件,Google上的...
Agorava 是一个实现了 OAuth 1.0a 和 OAuth 2.0 的框架,提供了简单的方式通过社交媒体进行身份认证的功能。 Eclipse的JavaScript插件 JSEditor JSEditor 是 Eclipse 下编辑 JavaScript 源码的插件,提供语法高亮...