1.加载netty依赖
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.39.Final</version>
</dependency>
2.服务器端程序编写
public class MyServer2 {
public static void main(String[] args) {
//负责接收客户端的连接请求
EventLoopGroup boosGroup=new NioEventLoopGroup(1);
//负责接收客户端读写请求
EventLoopGroup workerGroup=new NioEventLoopGroup();
try {
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(boosGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.handler(new LoggingHandler())
.childHandler(new ChannelInitializer<SocketChannel>() {
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
//解码器
pipeline.addLast(new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4, 0, 4));
//编码器
pipeline.addLast(new LengthFieldPrepender(4));
pipeline.addLast(new StringDecoder(CharsetUtil.UTF_8));
pipeline.addLast(new StringEncoder(CharsetUtil.UTF_8));
pipeline.addLast(new MyServerHandler());
}
});
ChannelFuture channelFuture = bootstrap.bind(9872).sync();
System.out.println("系统启动成功!!!");
channelFuture.channel().closeFuture().sync();
System.out.println("系统执行完成!!!");
}catch (Exception e){
e.printStackTrace();
}finally {
boosGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
public class MyServerHandler extends SimpleChannelInboundHandler<String> {
protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
System.out.println(ctx.channel().remoteAddress()+":"+msg);
// ctx.writeAndFlush("from server:"+UUID.randomUUID());
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}
3.客户端程序编写
public class MyClient2 {
public static void main(String[] args) {
EventLoopGroup group=new NioEventLoopGroup();
try {
Bootstrap boot = new Bootstrap();
boot.group(group)
.channel(NioSocketChannel.class)
.handler(new ChannelInitializer<SocketChannel>() {
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline=ch.pipeline();
pipeline.addLast(new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE,0,4,0,4));
pipeline.addLast(new LengthFieldPrepender(4));
pipeline.addLast(new StringDecoder(CharsetUtil.UTF_8));
pipeline.addLast(new StringEncoder(CharsetUtil.UTF_8));
pipeline.addLast(new MyClientHandler());
}
});
ChannelFuture channelFuture = boot.connect("localhost", 9872).sync();
channelFuture.channel().closeFuture().sync();
}catch (Exception e){
e.printStackTrace();
}finally {
group.shutdownGracefully();
}
}
}
public class MyClientHandler extends SimpleChannelInboundHandler<String> {
/**
*
* @param ctx 上下文请求对象
* @param msg 表示服务端发来的消息
* @throws Exception
*/
@Override
protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
/*System.out.println(ctx.channel().remoteAddress());
System.out.println("client 输出:"+msg);
ctx.writeAndFlush("来自 client:"+ LocalDateTime.now());*/
}
/**
* 如果没有这个方法,Client并不会主动发消息给Server
* 那么Server的channelRead0无法触发,导致Client的channelRead0也无法触发
* 这个channelActive可以让Client连接后,发送一条消息
* @param ctx
* @throws Exception
*/
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
ctx.writeAndFlush("hello world");
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}
上述代码基本是netty开发的模板代码,只是在需要不同的功能时,需要自定义符合业务逻辑的Handler ,如MyClientHandler 。