1.服务端构建
- 接收客户端请求,打印请求消息;
- 消息采用内置String作为编码与解码器;
- 开启信息输入监听线程,发送消息至客户端;
1.1 服务端消息处理类
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;import java.util.ArrayList;
import java.util.List;/*** @author : luobei* @date : 2024/10/23 11:16* @Description : 处理类:处理channel接收到的消息*/
public class NettyServerHandler extends ChannelInboundHandlerAdapter {public static List<Channel> channelList = new ArrayList<Channel>();@Overridepublic void channelActive(ChannelHandlerContext ctx) throws Exception {super.channelActive(ctx);channelList.add(ctx.channel());}@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {System.out.println("服务端收到消息:"+msg);}@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {System.out.println("服务端读取数据异常:");cause.printStackTrace();ctx.close();}
}
1.2 服务端启动类
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;/*** @author : luobei* @date : 2024/10/23 11:03*/
public class NettyServerProvider {private int port;public NettyServerProvider(int port){this.port = port;}//netty服务端启动public void start() throws InterruptedException {//用来接收进来的连接EventLoopGroup bossGroup = new NioEventLoopGroup();//用来处理已经被接收的连接,bossGroup接收到连接就会把连接信息注册到workerGroup上EventLoopGroup workerGroup = new NioEventLoopGroup();try {//nio服务的启动类ServerBootstrap bootstrap = new ServerBootstrap();//配置nio服务参数bootstrap.group(bossGroup,workerGroup).channel(NioServerSocketChannel.class) //说明一个新的Channel.option(ChannelOption.SO_BACKLOG,128) //设置Tcp最大缓存连接个数.childOption(ChannelOption.SO_KEEPALIVE,true) //设置保持连接.handler(new LoggingHandler(LogLevel.INFO)) //设置打印日志级别.childHandler(new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel socket) throws Exception {//管道注册handlerChannelPipeline pipeline = socket.pipeline();//编码通道处理pipeline.addLast("decode",new StringDecoder());//转码通道处理pipeline.addLast("encode",new StringEncoder());//处理接收到的请求pipeline.addLast(new NettyServerHandler());}});System.out.println("--------------服务端启动--------------");//监听输入框消息并发送给所有客户端new Thread(new Runnable() {@Overridepublic void run() {try {while (true){BufferedReader in = new BufferedReader(new InputStreamReader(System.in));String msg = null;msg = in.readLine();if (NettyServerHandler.channelList.size()>0){for (Channel channel : NettyServerHandler.channelList) {channel.writeAndFlush(msg);}}}} catch (IOException e) {throw new RuntimeException(e);}}}).start();//绑定端口,开始接收连接ChannelFuture channelFuture = null;channelFuture = bootstrap.bind(port).sync();channelFuture.channel().closeFuture().sync();} finally {bossGroup.shutdownGracefully();workerGroup.shutdownGracefully();}}public static void main(String[] args) throws InterruptedException {new NettyServerProvider(8888).start();}}
2.客户端构建
- 发起请求,与服务端建立连接;
- 监听服务端下发消息,并将信息打印出来;
- 开启信息输入监听线程,将消息发送值服务端;
2.1 客户端消息处理类
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;/*** @author : luobei* @date : 2024/10/23 13:15*/
public class NettyClientHandler extends ChannelInboundHandlerAdapter {public static Channel serverChannel = null;@Overridepublic void channelActive(ChannelHandlerContext ctx) throws Exception {super.channelActive(ctx);serverChannel = ctx.channel();}@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {System.out.println("客户端收到消息:"+msg);}@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {System.out.println("客户端读取数据异常:");cause.printStackTrace();ctx.close();}
}
2.2 客户端启动类
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;/*** @author : luobei* @date : 2024/10/23 13:20*/
public class NettyClientServer {//要请求的IP地址private String ip;//服务器端口private int port;public NettyClientServer(String ip, int port){this.ip = ip;this.port = port;}//启动服务private void start() throws InterruptedException {EventLoopGroup bossGroup = new NioEventLoopGroup();Bootstrap bootstrap = new Bootstrap();bootstrap.group(bossGroup).channel(NioSocketChannel.class).option(ChannelOption.SO_KEEPALIVE,true).handler(new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel socketChannel) throws Exception {ChannelPipeline pipeline = socketChannel.pipeline();pipeline.addLast("decode",new StringDecoder());pipeline.addLast("encode",new StringEncoder());socketChannel.pipeline().addLast(new NettyClientHandler());}});System.out.println("-----------客户端启动-----------");ChannelFuture future = bootstrap.connect(ip,port).sync();String msg = "客户端发起连接请求";Channel channel = future.channel();channel.writeAndFlush(msg);new Thread(new Runnable() {@Overridepublic void run() {try {while (true){BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));String msg = reader.readLine();channel.writeAndFlush(msg);}} catch (Exception e) {e.printStackTrace();}}}).start();}public static void main(String[] args) throws InterruptedException {new NettyClientServer("127.0.0.1",8888).start();}
}