maven
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.36.Final</version>
</dependency>
netty引导类
import java.net.InetSocketAddress;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
public class Aaa {
public static void main(String[] params) {
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(new NioEventLoopGroup(), new NioEventLoopGroup()).channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<Channel>() {
@Override
protected void initChannel(Channel ch) throws Exception {
// TODO Auto-generated method stub
ch.pipeline().addLast(new StringDecoder());
ch.pipeline().addLast(new StringEncoder());
ch.pipeline().addLast(new AaaHandler());
}
});
ChannelFuture future = bootstrap.bind(new InetSocketAddress(8080));
future.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture channelFuture) throws Exception {
if (channelFuture.isSuccess()) {
System.out.println("Server bound 8080");
} else {
System.err.println("Bind attempt failed");
channelFuture.cause().printStackTrace();
}
}
});
}
}
nettyhandler
import java.net.InetSocketAddress;
import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.bytes.ByteArrayEncoder;
import io.netty.handler.codec.string.StringEncoder;
public class AaaHandler extends SimpleChannelInboundHandler<String> {
private ChannelHandlerContext innerCtx;//内部ctx
private ChannelHandlerContext outCtx;//外部ctx
ChannelFuture connectFuture;
/**
* 在连接的时候创建一个netty客户端连接真正的服务器
*
*/
@Override
public void channelActive(ChannelHandlerContext ctx1) throws Exception {
outCtx = ctx1;
Bootstrap bootstrap = new Bootstrap();
bootstrap.channel(NioSocketChannel.class).handler(new ChannelInitializer<Channel>() {
@Override
protected void initChannel(Channel ch) throws Exception {
ch.pipeline().addLast(new StringEncoder()).addLast(new ByteArrayEncoder())
.addLast(new SimpleChannelInboundHandler<ByteBuf>() {
// 内层建立的连接,从这里接收内层的应答,在这里是服务端的应答
@Override
protected void channelRead0(ChannelHandlerContext ctx, ByteBuf in) throws Exception {
/**
* 如果接到消息,则将该消息回复给外部
*/
if (outCtx != null && outCtx.channel().isActive()) {
outCtx.writeAndFlush(in.copy());
}
}
/**
* 内部如果建立链接,就将innerCtx置为属性
*/
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
innerCtx = ctx;
System.out.println("链接服务" + ctx.channel().toString());
}
/**
* 内部链接如果关闭,外部链接也关闭
*/
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
if (outCtx != null && outCtx.channel().isActive()) {
outCtx.close();
}
}
});
}
});
bootstrap.group(ctx1.channel().eventLoop());// 关键在这里。把外层channel的eventLoop挂接在内层上
connectFuture = bootstrap.connect(
// new InetSocketAddress("192.168.60.49", 23456));
new InetSocketAddress("localhost", 8888));
}
/**
* 如果接到数据,则让内部链接发送数据
*/
@Override
protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
// TODO Auto-generated method stub
if (connectFuture.isDone()) {
// do something with the data
// channel并不共享,共享的是线程EventLoop,所以如果想向内层转发的话
// 需要持有内层的channel
if (innerCtx != null && innerCtx.channel().isActive()) {
innerCtx.writeAndFlush(msg);
}
}
}
/**
* 如果断开外部链接,则内部链接也断开
*/
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
if (innerCtx != null && innerCtx.channel().isActive()) {
innerCtx.close();
}
}
}
以上例子是tcp:8080->tcp:8888