基于Java的Netty框架监听收发

创建Netty收发线程池,配置监听端口,配置服务实现类。

Config.nNettyPort 自定义监听端口

public class ServerThread extends Thread
{
    /**定义一个map,key存放loginCode,value存放ctx**/
    //保证线程安全使用ConcurrentHashMap
    //public static ConcurrentHashMap <ChannelHandlerContext, DTU> mapDtu = new ConcurrentHashMap<>();

    public void run()
    {
        //boss线程监听端口,worker线程负责数据读写
        EventLoopGroup boss = new NioEventLoopGroup(); // 一组线程负责用于处理Client端的连接请求
        EventLoopGroup worker = new NioEventLoopGroup(); // 另一组线程负责信息的交互

        try
        {
            ServerBootstrap bootstrap = new ServerBootstrap();       // 辅助工具类,用于服务器通道的一系列配置
            //设置线程池
            bootstrap.group(boss, worker);
            //设置socket工厂
            bootstrap.channel(NioServerSocketChannel.class);

            //设置管道工厂
            bootstrap.childHandler(new ChannelInitializer<SocketChannel>() {
                @Override
                protected void initChannel(SocketChannel socketChannel) throws Exception {
                    //获取管道
                    ChannelPipeline pipeline = socketChannel.pipeline();
                    //处理类
                    pipeline.addLast(new DTUFrameHandler());
                }
            });

            //设置TCP参数
            //1.链接缓冲池的大小(ServerSocketChannel的设置)
            bootstrap.option(ChannelOption.SO_BACKLOG, Config.nNettyBacklog);
            //bootstrap.option(ChannelOption.SO_SNDBUF, Config.nNettySendBuf);
            //bootstrap.option(ChannelOption.SO_RCVBUF, Config.nNettyRcvBuf);
            //维持链接的活跃,清除死链接(SocketChannel的设置)
            bootstrap.childOption(ChannelOption.SO_KEEPALIVE, true);
            //关闭延迟发送
            bootstrap.childOption(ChannelOption.TCP_NODELAY, true);

            //绑定端口
            ChannelFuture cf1 = bootstrap.bind(Config.nNettyPort).sync();

            //等待服务端监听端口关闭
            cf1.channel().closeFuture().sync();                           // 等待关闭,异步,阻塞当前线程
        }
        catch (InterruptedException e)
        {
            e.printStackTrace();
        }
        finally
        {
            //优雅退出,释放线程池资源
            boss.shutdownGracefully();
            worker.shutdownGracefully();
        }

    }
}

 DTUFrameHandler 服务实现类(接收设备心跳、返回信息)

public class DTUFrameHandler extends ChannelInboundHandlerAdapter
{
    //key: channel id
    @Override
    public void channelActive(ChannelHandlerContext ctx)
    {
        DTU.printChannelMessage(ctx,"New client connected");
    }

    @Override
    public void channelRead (final ChannelHandlerContext ctx, Object msg)
    {
        ByteBuf buf  = (ByteBuf) msg;
        byte[] req = new byte[buf.readableBytes()];
        buf.readBytes(req);
        //释放内存数据
        buf.release();

        String channel_id = DTU.getChannelId(ctx);

        DTU.printChannelMessage(ctx,channel_id + " Read data:[" + ToHex.ToHex(req) + "]");
    }

    /** 连接中断,去除ctxMap中相应的ctx**/
    @Override
    public void channelInactive(ChannelHandlerContext ctx)
    {
        DTU.printChannelMessage(ctx, "Client disconnected");
    }

    @Override
    public  void exceptionCaught(ChannelHandlerContext ctx, Throwable t)
    {
        DTU.printChannelMessage(ctx, "Client exception");
    }

根据所需创建发送信息 

cmd.sendDate 根据设备实际情况创建要发送的指令

ctx.channel().writeAndFlush(Unpooled.copiedBuffer(cmd.sendData));
String str_command = " data:[" + ToHex.ToHex(cmd.sendData)+ "]";
DTU.printChannelMessage(ctx,str_command);

pom以及工具类

<dependency>
	<groupId>io.netty</groupId>
	<artifactId>netty</artifactId>
	<version>3.10.5.Final</version>
</dependency>

<dependency>
	<groupId>io.netty</groupId>
	<artifactId>netty-all</artifactId>
	<version>4.1.42.Final</version>
</dependency>
static char[] BCDCode=new char[]{'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','0'};
    public static String  ToHex(byte[] bytes)
    {
        int[] read_ints = new int[bytes.length];
        for (int i = 0; i < bytes.length; i++) {
            if ((int) bytes[i] > 0) {
                read_ints[i] = (int) bytes[i];
            } else {
                read_ints[i] = (int) bytes[i] + 256;
            }
        }
        //System.out.println(Arrays.toString(read_ints));
        String str_addr = "";
        String EachByteAddress;
        for (int addr_b : read_ints) {
            EachByteAddress = BCDCode[addr_b / 16]+""+ BCDCode[addr_b % 16] +" ";
            str_addr =str_addr + EachByteAddress;
        }
        return str_addr;
    }
public static String  getChannelId(ChannelHandlerContext ctx)
    {
        return ctx.channel().id().toString();
    }

收发信息如下

新连接进来创建ctx通道,携带心跳信息。

发送指令

回收信息

 

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个基于Netty框架Java登录代码示例: ```java import io.netty.bootstrap.Bootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelOption; 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; public class LoginClient { private String host; private int port; public LoginClient(String host, int port) { this.host = host; this.port = port; } public void start() { Bootstrap bootstrap = new Bootstrap(); bootstrap.group(new NioEventLoopGroup()) .channel(NioSocketChannel.class) .option(ChannelOption.TCP_NODELAY, true) .handler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel socketChannel) throws Exception { socketChannel.pipeline().addLast(new StringEncoder()); socketChannel.pipeline().addLast(new StringDecoder()); socketChannel.pipeline().addLast(new LoginClientHandler()); } }); try { ChannelFuture future = bootstrap.connect(host, port).sync(); future.channel().closeFuture().sync(); } catch (InterruptedException e) { e.printStackTrace(); } finally { group.shutdownGracefully(); } } public static void main(String[] args) { LoginClient client = new LoginClient("localhost", 8888); client.start(); } } class LoginClientHandler extends SimpleChannelInboundHandler<String> { @Override protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception { // 处理登录结果 } @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { // 发送登录请求 String loginMsg = "login:username,password"; ctx.writeAndFlush(loginMsg); } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { cause.printStackTrace(); ctx.close(); } } ``` 在代码中,我们创建了一个`LoginClient`类,用于连接服务端并发送登录请求。在`start()`方法中,我们利用Netty的`Bootstrap`创建一个客户端的Bootstrap实例,设置了NioSocketChannel作为通道类型,设置了TCP_NODELAY选项,然后添加了一个`ChannelInitializer`,其中`initChannel()`方法用于添加`StringDecoder`和`StringEncoder`,以及自定义的`LoginClientHandler`。 `LoginClientHandler`继承了`SimpleChannelInboundHandler`,并实现了`channelRead0()`、`channelActive()`和`exceptionCaught()`方法。在`channelActive()`方法中,我们发送了一个登录请求,`channelRead0()`方法用于处理服务端返回的登录结果,`exceptionCaught()`方法用于处理异常情况。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值