netty简单的转发例子

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

猜你喜欢

转载自blog.csdn.net/dmw412724/article/details/113272952