服务端:
//服务端
public class Server {
public static void main(String[] args) {
//创建两个线程组
EventLoopGroup connectGroup = new NioEventLoopGroup();//接受客户端连接
EventLoopGroup workGroup = new NioEventLoopGroup();//处理实际业务操作
try {//创建server配置类
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(connectGroup,workGroup)//支持链式编程,进行配置
//指定使用NioServerSocketChannel这种类型(服务端)的通道
.channel(NioServerSocketChannel.class)
//ChannelInitializer:服务器Channel通道初始化设置的抽象类
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override //初始化操作:编解码,绑定处理逻辑等
protected void initChannel(SocketChannel channel) throws Exception {
//使用 childHandler 去绑定具体的 事件处理器
ChannelPipeline pipeline = channel.pipeline();
pipeline.addLast(new ServerHandler());//绑定服务端数据处理
}
});
//绑定端口,调用sync()方法来执行同步阻塞,直到绑定完成
ChannelFuture sync = bootstrap.bind(9527).sync();
//获取该Channel的CloseFuture,并且阻塞当前线程直到绑定的端口关闭才会执行关闭通道
sync.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
//关闭线程组
connectGroup.shutdownGracefully();
workGroup.shutdownGracefully();
}
}
}
服务端业务处理
/*
* 服务端处理数据类
* */
// SimpleChannelInboundHandler: 只处理入站消息(接受到的)
public class ServerHandler extends SimpleChannelInboundHandler<ByteBuf> {
//CTRL+O: 重写父类方法
//对数据进行处理
@Override
protected void channelRead0(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf) throws Exception {
byte[] data=new byte[byteBuf.readableBytes()];//创建byte数组
byteBuf.readBytes(data);//将数据读取到数组中
//转String
String str=new String(data,"utf-8");
System.out.println("服务端收到数据:"+str);
//返回数据给客户端 Ctrl+Alt+V :自动补全返回值
ByteBuf byteBuf1 = Unpooled.copiedBuffer("我已经接受到数据".getBytes());//转byteBuf
channelHandlerContext.writeAndFlush(byteBuf1);//发送给客户端
}
//捕获异常
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();//打印信息
ctx.close();//关闭通道
}
}
客户端
//客户端
public class Client {
public static void main(String[] args) throws Exception {
//实际业务处理线程组
EventLoopGroup workGroup = new NioEventLoopGroup();
//创建客户端配置类
Bootstrap bootstrap=new Bootstrap();
//链式配置
bootstrap.group(workGroup)
.channel(NioSocketChannel.class) //指定客户端类型通道
.handler(new ChannelInitializer<SocketChannel>() { //配置初始化
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
socketChannel.pipeline().addLast(new ClientHandler());//绑定客户端数据处理对象
}
});
//与服务端连接,调用sync()方法来执行同步阻塞,直到连接完成
ChannelFuture sync =bootstrap.connect("127.0.0.1",9527).sync();
//向服务端发送数据 Unpooled: netty提供的工具类,可以将其他类型转为buf类型
sync.channel().writeAndFlush(Unpooled.copiedBuffer("我是客户端".getBytes()));
//开启同步阻塞监听,直到断开连接才关闭通道
sync.channel().closeFuture().sync();
workGroup.shutdownGracefully();
}
}
客户端业务处理
//客户端处理数据
public class ClientHandler extends SimpleChannelInboundHandler<ByteBuf> {
//处理服务端返回的数据
@Override
protected void channelRead0(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf) throws Exception {
byte[] data = new byte[byteBuf.readableBytes()];//byteBuf.readableBytes():获取可用的长度
byteBuf.readBytes(data);//数据读取到数组中
String string = new String(data,"utf-8");
System.out.println("客户端接受到服务端返回的数据:"+string);
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();//打印信息
ctx.close();//关闭通道
}
}
到这里一个客户端服务端简单通信就完成了,比nio简单多了,是不是,工具用的idea,先开启服务端,再开启客户端: