- github地址:https://github.com/netty/netty
- 官網(wǎng):http://netty.io
- Demo地址:
一、Netty Server端
- IDE和構(gòu)建工具:eclipse meaven
- Netty版本號:5.0.0.Alpha2
1. 新建工程谎懦,通過meaven導(dǎo)入Netty的庫包
找到工程中的pom.xml文件,在dependencies中添加如下代碼
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>5.0.0.Alpha2</version>
</dependency>
2. 創(chuàng)建NettyServer
新建NettyServer類
package com.jiutianbian.NettyTest;
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); // 連接數(shù)
bootstrap.option(ChannelOption.TCP_NODELAY, true); // 不延遲,消息立即發(fā)送
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());// 添加NettyServerHandler,用來處理Server端接收和處理消息的邏輯
}
});
ChannelFuture channelFuture = bootstrap.bind(port).sync();
if (channelFuture.isSuccess()) {
System.err.println("啟動Netty服務(wù)成功似舵,端口號:" + this.port);
}
// 關(guān)閉連接
channelFuture.channel().closeFuture().sync();
} catch (Exception e) {
System.err.println("啟動Netty服務(wù)異常审丘,異常信息:" + e.getMessage());
e.printStackTrace();
} finally {
boss.shutdownGracefully();
worker.shutdownGracefully();
}
}
public static void main(String[] args) throws InterruptedException {
new NettyServer(10086);
}
}
3. 創(chuàng)建NettyServerHandler,用來接收和回復(fù)Client端的消息
新建NettyServerHandler類推正,用來實(shí)現(xiàn)Server端接收和處理消息的邏輯
package com.jiutianbian.NettyTest;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import java.io.UnsupportedEncodingException;
public class NettyServerHandler extends ChannelHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
ByteBuf buf = (ByteBuf) msg;
String recieved = getMessage(buf);
System.err.println("服務(wù)器接收到客戶端消息:" + recieved);
try {
ctx.writeAndFlush(getSendByteBuf("你好,客戶端"));
System.err.println("服務(wù)器回復(fù)消息:你好宝惰,客戶端");
} 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, "UTF8");
} 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;
}
}
4. 啟動Server端
Server啟動后的日志輸出植榕,如下圖所示
一、Netty Client端
1. 新建工程尼夺,通過meaven導(dǎo)入Netty的庫包
導(dǎo)入代碼同上面的Server端代碼
2. 創(chuàng)建NettyClient
新建NettyClient類
package com.jiutianbian.NettyClinetTest;
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 {
/*
* 服務(wù)器端口號
*/
private int port;
/*
* 服務(wù)器IP
*/
private String host;
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 channelFuture = bootstrap.connect(host, port).sync();
if (channelFuture.isSuccess()) {
System.err.println("連接服務(wù)器成功");
}
channelFuture.channel().closeFuture().sync();
} finally {
eventLoopGroup.shutdownGracefully();
}
}
public static void main(String[] args) throws InterruptedException {
new NettyClient(10086, "localhost");
}
}
3. 創(chuàng)建NettyClientHandler尊残,用來向Server端的發(fā)送消息并處理回復(fù)信息
新建NettyClientHandler類,用來實(shí)現(xiàn)Server端接收和處理消息的邏輯
package com.jiutianbian.NettyClinetTest;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import java.io.UnsupportedEncodingException;
public class NettyClientHandler extends ChannelHandlerAdapter {
private ByteBuf firstMessage;
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
byte[] data = "你好淤堵,服務(wù)器".getBytes();
firstMessage = Unpooled.buffer();
firstMessage.writeBytes(data);
ctx.writeAndFlush(firstMessage);
System.err.println("客戶端發(fā)送消息:你好寝衫,服務(wù)器");
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg)
throws Exception {
ByteBuf buf = (ByteBuf) msg;
String rev = getMessage(buf);
System.err.println("客戶端收到服務(wù)器消息:" + rev);
}
private String getMessage(ByteBuf buf) {
byte[] con = new byte[buf.readableBytes()];
buf.readBytes(con);
try {
return new String(con, "UTF8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return null;
}
}
}
4. 啟動Client端
Client啟動后的Client端的日志輸出,如下圖所示
Server端日志輸出粘勒,此時(shí)如下