Netty

0 篇文章 0 订阅

Netty

NettyServer
package netty01;


import java.net.InetSocketAddress;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
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 static final int PORT = 6666;

	public static void main(String[] args) throws Exception {
		new NettyServer().start();
	}
	
	
	public void start() {
		
		/**
		 * 1、NioEventLoopGroup 是用来处理I/O操作的多线程事件循环器
		 * 		parentGroup       用来接收进来的连接,被称为‘boss’
		 * 		childGroup		 用来处理已经被接收的连接,一旦‘boss’接收到连接,就会把连接信息注册到‘worker’上
		 * 
		 * 2、ServerBootstrap 是一个启动 NIO 服务的辅助启动类
		 */
		EventLoopGroup parentGroup = new NioEventLoopGroup();
		EventLoopGroup childGroup = new NioEventLoopGroup();
		try{
			ServerBootstrap serverBootstrap = new ServerBootstrap();
			serverBootstrap.group(parentGroup, childGroup)
				.channel(NioServerSocketChannel.class)//指定使用NIO的传输Channel,指定信道类型
				.localAddress(new InetSocketAddress(PORT))//设置socket地址使用所选端
				.childHandler(new ChannelInitializer<SocketChannel>() {
					
				    //当有一个新的连接被接受,一个新的子Channel将被创建,ChannelInitializer添加EchoServerHandler到Channel的ChannelPipeline,
					@Override
					protected void initChannel(SocketChannel ch) throws Exception {
						ch.pipeline().addLast(new ServerHandler());
					}
				});
			ChannelFuture future = serverBootstrap.bind().sync();//绑定的服务器,sync等待服务器关闭,调用sync()的原因是当前线程阻塞
			future.channel().closeFuture().sync();//关闭Channel和块
		
		} catch (InterruptedException e) {
			
			e.printStackTrace();
		}finally{
			
			//关闭EventLoopGroup,释放所有资源
			parentGroup.shutdownGracefully();
			childGroup.shutdownGracefully();
		}
	}
}
ServerHandler
package netty01;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.CharsetUtil;

public class ServerHandler extends ChannelInboundHandlerAdapter{
	
	private Logger logger = LoggerFactory.getLogger(ServerHandler.class);

	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
		logger.debug("exceptionCaught: "+cause.getMessage());
		cause.printStackTrace();
	}
	
	/**
	 * 1    每个信息入站都会调用,覆盖该方法是因为我们需要处理所有接收到的数据;
	 */
	@Override
	public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
		logger.debug("----------server--------channelRead ");
		logger.debug("msg所属类型: "+msg.getClass().getName());
		ByteBuf in = (ByteBuf)msg;
		logger.debug("channelRead: "+in.toString(CharsetUtil.UTF_8));
		ctx.writeAndFlush("hello client");
		
		//ctx.write(Object) 方法不会使消息写入到通道上,他被缓冲在了内部,需要调用 ctx.flush() 方法来把缓冲区中数据强行输出
		ctx.write("client....");
		ctx.flush();
	}
	
	/**
	 * 1    通知处理器最后的channelRead()是当前处理中的最后一条消息调用;
	 */
	@Override
	public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
		logger.debug("----------server--------channelReadComplete ");
	}
	
	@Override
	public void channelActive(ChannelHandlerContext ctx) throws Exception {
		//客户端连接到服务器时会用到此方法
		logger.debug("---------server---------channelActive ");
	}
}
NettyClient
package netty01;

import java.net.InetSocketAddress;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;

public class NettyClient {

	private static final String IP = "localhost";
	private static final int PORT = 6666;

	public static void main(String[] args) {
		new NettyClient().start();
	}
	
	public void start() {
		NioEventLoopGroup eventLoopGroup = new NioEventLoopGroup();
		try {
			Bootstrap bootstrap = new Bootstrap();//创建Bootstrap
			
			bootstrap.group(eventLoopGroup)//指定EventLoopGroup来处理客户端事件,由于我们NIO传输,所以用到了NioEventLoopGroup的实现
				.channel(NioSocketChannel.class)//使用的Channel类型是一个用于NIO传输,也可以使用和服务器不一样的类型
				.remoteAddress(new InetSocketAddress(IP, PORT))//设置服务器的InetSocketAddress
				.handler(new ChannelInitializer<SocketChannel>() {//当建立一个连接和一个新的通道时,创建添加到 EchoClientHandler 实例 到 channelpipeline
	
					@Override
					protected void initChannel(SocketChannel ch) throws Exception {
						ch.pipeline().addLast(new ClientHandle());
					}
				});
			ChannelFuture future = bootstrap.connect().sync();//连接到远程,等待连接完成
			future.channel().closeFuture().sync();// 阻塞直到Channel关闭
			
		}catch (InterruptedException e) {
			e.printStackTrace();
		}finally {
			eventLoopGroup.shutdownGracefully();//用shutdownGracefully来关闭线程池和释放所有资源
		}
	}
}
ClientHandle
package netty01;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.util.CharsetUtil;

public class ClientHandle extends SimpleChannelInboundHandler<ByteBuf>{
	private Logger logger = LoggerFactory.getLogger(ClientHandle.class);
	
	@Override
	public void channelActive(ChannelHandlerContext ctx) throws Exception {
		logger.debug("---------client---------channelActive ");
		//.当被通知该 channel 是活动的时候就发送信息
		ctx.writeAndFlush(Unpooled.copiedBuffer("Netty rock", CharsetUtil.UTF_8));
	}
	
	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
		logger.debug(cause.getMessage());
		cause.printStackTrace();
		ctx.close();
	}

	@Override
	protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) throws Exception {
		logger.debug("---------clients---------channelRead0 ");
		logger.debug("client msg:"+msg.toString(CharsetUtil.UTF_8));
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值