demo说明
这个demo演示的是启动客户端时会给服务器发送一条消息,服务器会将这条消息发回给客户端
Client
/**
* @author YanYu
* @create 2021-01-18 9:51
*/
public class EchoClient {//客户端启动类
private String host;
private int port;
public EchoClient(String host, int port) {
this.host = host;
this.port = port;
}
public void start() throws InterruptedException {
EventLoopGroup group=new NioEventLoopGroup();
try {
Bootstrap b=new Bootstrap();
b.group(group)
.channel(NioSocketChannel.class)//配置管道类型
.remoteAddress(host,port)//配置服务器地址
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
socketChannel.pipeline().addLast(new EchoClientHandler());
}
});
ChannelFuture f=b.connect().sync();//连接服务器
f.channel().closeFuture().sync();//等待客户端链路关闭
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
group.shutdownGracefully().sync();//释放Nio线程组
}
}
public static void main(String[] args) throws InterruptedException {
new EchoClient("127.0.0.1",8080).start();
}
}
/**
* @author YanYu
* @create 2021-01-18 9:42
*/
//此注解是ChannelHanler接口中的注解,标识这个handler可以被其他Channel安全的共享
@ChannelHandler.Sharable
//客户端事件处理类,个人觉得非常像js的CallBack回调函数
public class EchoClientHandler extends SimpleChannelInboundHandler<ByteBuf> {
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
//当与服务器建立TCP链路时触发
System.out.println("服务器连接成功。。。。。");
//发送数据
ctx.writeAndFlush(Unpooled.copiedBuffer("Netty rocks", CharsetUtil.UTF_8));
}
@Override
protected void channelRead0(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf) throws Exception {
//Channel中的数据读到ByteBuf触发
System.out.println("Client receive:"+byteBuf.toString(CharsetUtil.UTF_8));
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
//异常时触发
cause.printStackTrace();//打印异常
ctx.close();//关闭通道
}
}
Server
/**
* @author YanYu
* @create 2021-01-18 9:24
*/
public class EchoServer {//服务端启动类
private final int port;
public EchoServer(int port){
this.port=port;
}
public static void main(String[] args) throws InterruptedException {
new EchoServer(8080). start();
}
public void start() throws InterruptedException {
final EchoServerHandler serverHandler=new EchoServerHandler();
//创建两个Nio事件线程组,一个负责监听客户端链接,一个对客户的请求进行处理
EventLoopGroup bossGroup=new NioEventLoopGroup();
EventLoopGroup workGroup=new NioEventLoopGroup();
try {
ServerBootstrap b=new ServerBootstrap();//开启Nio服务的辅助启动类
b.group(bossGroup,workGroup)
.channel(NioServerSocketChannel.class)//设置管道类型
.localAddress(new InetSocketAddress(port))//设置端口
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
socketChannel.pipeline().addLast(serverHandler);
}
});
ChannelFuture f=b.bind().sync();//绑定端口,开启服务
f.channel().closeFuture().sync();//等待服务端监听端口关闭
} finally {
bossGroup.shutdownGracefully().sync();//关闭nio线程组
workGroup.shutdownGracefully().sync();
}
}
}
/**
* @author YanYu
* @create 2021-01-18 9:12
*/
@ChannelHandler.Sharable //表示一个channelhandler可以被多个channel安全共享
public class EchoServerHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
ByteBuf in= (ByteBuf) msg;
System.out.println("Server receive:"+in.toString(CharsetUtil.UTF_8));
ctx.write(in);
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
//channel中数据读取完成触发
ctx.writeAndFlush(Unpooled.EMPTY_BUFFER).
addListener(ChannelFutureListener.CLOSE);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}