Netty通訊框架Java實現小記
阿新 • • 發佈:2019-01-27
1、Netty介紹
Netty通俗地說就是一套Socket通訊框架,提供非同步的、事件驅動的網路應用程式框架和工具,可快速開發高效能、高可靠性的網路伺服器和客戶端程式
2、Netty的特性
1)設計
統一的API,適用於不同的協議(阻塞和非阻塞)
基於靈活、可擴充套件的事件驅動模型
高度可定製的執行緒模型
可靠的無連線資料Socket支援(UDP)
2)效能
更好的吞吐量,低延遲
更省資源
儘量減少不必要的記憶體拷貝
3)安全
完整的SSL/TLS和STARTTLS的支援
能在Applet與Android的限制環境執行良好
4)健壯性
不再因過快、過慢或超負載連線導致OutOfMemoryError
不再有在高速網路環境下NIO讀寫頻率不一致的問題
5)易用
完善的JavaDoc,使用者指南和樣例
簡潔簡單
3、下載Jar包
http://netty.io/downloads.html 下載
引入netty-all-4.1.4.Final.jar包到工程
4、Server端程式碼示例:
6、總結:server和client端主要是建立連線,資料接收和傳送主要是繼承ChannelInboundHandlerAdapter類,過載channelRead等函式。
Netty通俗地說就是一套Socket通訊框架,提供非同步的、事件驅動的網路應用程式框架和工具,可快速開發高效能、高可靠性的網路伺服器和客戶端程式
2、Netty的特性
1)設計
統一的API,適用於不同的協議(阻塞和非阻塞)
基於靈活、可擴充套件的事件驅動模型
高度可定製的執行緒模型
可靠的無連線資料Socket支援(UDP)
2)效能
更好的吞吐量,低延遲
更省資源
儘量減少不必要的記憶體拷貝
3)安全
完整的SSL/TLS和STARTTLS的支援
能在Applet與Android的限制環境執行良好
4)健壯性
不再因過快、過慢或超負載連線導致OutOfMemoryError
不再有在高速網路環境下NIO讀寫頻率不一致的問題
5)易用
完善的JavaDoc,使用者指南和樣例
簡潔簡單
3、下載Jar包
http://netty.io/downloads.html 下載
引入netty-all-4.1.4.Final.jar包到工程
4、Server端程式碼示例:
package cn.netty; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelOption; import io.netty.channel.ChannelPipeline; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioServerSocketChannel; public class NettyServer { private int port; public NettyServer(int port) { this.port = port; bind(); } private void bind() { EventLoopGroup boss = new NioEventLoopGroup(); EventLoopGroup worker = new NioEventLoopGroup(); try { ServerBootstrap bootstrap = new ServerBootstrap(); bootstrap.group(boss, worker); bootstrap.channel(NioServerSocketChannel.class); bootstrap.option(ChannelOption.SO_BACKLOG, 1024); //連線數 bootstrap.option(ChannelOption.TCP_NODELAY, true); //不延遲,訊息立即傳送 bootstrap.childOption(ChannelOption.SO_KEEPALIVE, true); //長連線 bootstrap.childHandler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel socketChannel) throws Exception { ChannelPipeline p = socketChannel.pipeline(); p.addLast(new NettyServerHandler()); } }); ChannelFuture f = bootstrap.bind(port).sync(); if (f.isSuccess()) { System.out.println("啟動Netty服務成功,埠號:" + this.port); } //Wait until the server socket is closed. f.channel().closeFuture().sync(); } catch (Exception e) { System.out.println("啟動Netty服務異常,異常資訊:" + e.getMessage()); e.printStackTrace(); } finally { boss.shutdownGracefully(); worker.shutdownGracefully(); } } public static void main(String[] args) throws InterruptedException { NettyServer server= new NettyServer(9999); } }
5、Client端程式碼示例:package cn.netty; import java.io.UnsupportedEncodingException; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; public class NettyServerHandler extends ChannelInboundHandlerAdapter { @Override public void channelRead(ChannelHandlerContext ctx, Object msg) { ByteBuf buf = (ByteBuf) msg; String recieved = getMessage(buf); System.out.println("伺服器接收到訊息:" + recieved); try { ctx.writeAndFlush(getSendByteBuf("Message")); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } /* * 從ByteBuf中獲取資訊 使用UTF-8編碼返回 */ private String getMessage(ByteBuf buf) { byte[] con = new byte[buf.readableBytes()]; buf.readBytes(con); try { return new String(con, "UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); return null; } } private ByteBuf getSendByteBuf(String message) throws UnsupportedEncodingException { byte[] req = message.getBytes("UTF-8"); ByteBuf pingMessage = Unpooled.buffer(); pingMessage.writeBytes(req); return pingMessage; } }
package cn.netty; import io.netty.bootstrap.Bootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelOption; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioSocketChannel; public class NettyClient { private int port;//伺服器埠號 private String host;//伺服器IP public NettyClient(int port, String host) throws InterruptedException { this.port = port; this.host = host; start(); } private void start() throws InterruptedException { EventLoopGroup eventLoopGroup = new NioEventLoopGroup(); try { Bootstrap bootstrap = new Bootstrap(); bootstrap.channel(NioSocketChannel.class); bootstrap.option(ChannelOption.SO_KEEPALIVE, true); bootstrap.group(eventLoopGroup); bootstrap.remoteAddress(host, port); bootstrap.handler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel socketChannel) throws Exception { socketChannel.pipeline().addLast(new NettyClientHandler()); }}); ChannelFuture future = bootstrap.connect(host, port).sync(); if (future.isSuccess()) { //SocketChannel socketChannel = (SocketChannel) future.channel(); System.out.println("----------------connect server success----------------"); } // Wait until the connection is closed. future.channel().closeFuture().sync(); } finally { eventLoopGroup.shutdownGracefully(); } } public static void main(String[] args) throws InterruptedException { NettyClient client = new NettyClient(9999,"localhost"); } }
package cn.netty;
import java.io.UnsupportedEncodingException;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
public class NettyClientHandler extends ChannelInboundHandlerAdapter {
private ByteBuf firstMessage;
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
byte[] data = "伺服器,給我一個Message".getBytes();
firstMessage=Unpooled.buffer();
firstMessage.writeBytes(data);
ctx.writeAndFlush(firstMessage);
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
ByteBuf buf = (ByteBuf) msg;
String rev = getMessage(buf);
System.out.println("客戶端收到伺服器資料:" + rev);
}
private String getMessage(ByteBuf buf) {
byte[] con = new byte[buf.readableBytes()];
buf.readBytes(con);
try {
return new String(con, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return null;
}
}
}
6、總結:server和client端主要是建立連線,資料接收和傳送主要是繼承ChannelInboundHandlerAdapter類,過載channelRead等函式。