25.Android网络通讯-Netty(TCP服务端)

该博客展示了如何使用Netty实现一个简单的服务器,包括数据初始化、启动服务器、接收和处理数据,以及发送数据的流程。通过NioEventLoopGroup、ServerBootstrap和ChannelInitializer等组件配置,实现了TCP服务端的创建,并处理不同类型的API请求,如心跳响应和BLE相关操作。同时,服务器还具备超时管理和连接状态监听功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

导包

数据初始化

public class NettyServer {
    public static Map<String, Channel> getMap() {
        return map;
    }

    public static void setMap(Map<String, Channel> map) {
        NettyServer.map = map;
    }


    private static Map<String, Channel> map = new ConcurrentHashMap<String, Channel>();
    public void bind(int port) throws Exception {

        EventLoopGroup bossGroup = new NioEventLoopGroup(); //bossGroup就是parentGroup,是负责处理TCP/IP连接的
        EventLoopGroup workerGroup = new NioEventLoopGroup(); //workerGroup就是childGroup,是负责处理Channel(通道)的I/O事件

        ServerBootstrap sb = new ServerBootstrap();
        sb.group(bossGroup, workerGroup)
            .channel(NioServerSocketChannel.class)
            .option(ChannelOption.SO_BACKLOG, 128) //初始化服务端可连接队列,指定了队列的大小128
            .childOption(ChannelOption.SO_KEEPALIVE, true) //保持长连接
            .childHandler(new ChannelInitializer<SocketChannel>() {  // 绑定客户端连接时候触发操作
                @Override
                protected void initChannel(SocketChannel sh) throws Exception {
                    sh.pipeline()
//                        .addLast(   new MessagePacketDecoder()) //解码request
//                        .addLast(new MessagePacketEncoder()) //编码response
                        .addLast(new HelloServerHandler()); //使用ServerHandler类来处理接收到的消息
                }
            });
        //绑定监听端口,调用sync同步阻塞方法等待绑定操作完成,完成后返回ChannelFuture类似于JDK中Future
        ChannelFuture future = sb.bind(port).sync();

        if (future.isSuccess()) {
            System.out.println("服务端启动成功");
        } else {
            System.out.println("服务端启动失败");
            future.cause().printStackTrace();
            bossGroup.shutdownGracefully(); //关闭线程组
            workerGroup.shutdownGracefully();
        }

        //成功绑定到端口之后,给channel增加一个 管道关闭的监听器并同步阻塞,直到channel关闭,线程才会往下执行,结束进程。
        future.channel().closeFuture().sync();

    }
}

接收数据,处理数据

public class HelloServerHandler extends ChannelInboundHandlerAdapter {

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        ByteBuf inBuffer = (ByteBuf) msg;

        String received = inBuffer.toString(CharsetUtil.UTF_8);
        //取到数据
        Log.e("TAG", "数据:" +received);

        //返回数据
        Request Requests = JSONUtils.parseJSON(received, Request.class);
        String api_name = Requests.getApi_name();
       
        String tojson = "";
        switch (api_name) {

            case "startBleCheck_req":
                EventBus.getDefault().post(new MessageWrap("1",received));

                break;

            case "heartbeat_req":
                ReponseHeartbeat reponseHeartbeat =new ReponseHeartbeat();
                reponseHeartbeat.setApi_name("heartbeat_res");
                reponseHeartbeat.setCode("0");
                reponseHeartbeat.setData("51653658");
                reponseHeartbeat.setMsg("new");
                tojson = JSONUtils.tojson(reponseHeartbeat);
                break;
            case "bleCheckConfirm_req":
                ReponseConint reponseConint =new ReponseConint();
                reponseConint.setApi_name("bleCheckConfirm_resp");
                reponseConint.setCode("0");
                reponseConint.setMsg("success");
                tojson = JSONUtils.tojson(reponseConint);
                break;



            default:
                break;
        }

    

        ctx.write(Unpooled.copiedBuffer( tojson, CharsetUtil.UTF_8));
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        ctx.writeAndFlush(Unpooled.EMPTY_BUFFER)
             ;
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        super.channelActive(ctx);
        Log.e("TAG", "数据:" +"CLIENT"+getRemoteAddress(ctx)+" 接入连接");
        NettyServer.getMap().put("TEST", ctx.channel());
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        super.channelInactive(ctx);
        NettyServer.getMap().remove("TEST");
        ctx.close();
    }

    public static String getRemoteAddress(ChannelHandlerContext ctx){
        String socketString = "";
        socketString = ctx.channel().remoteAddress().toString();
        return socketString;

    }
    public static String getIPString(ChannelHandlerContext ctx){
        String ipString = "";
        String socketString = ctx.channel().remoteAddress().toString();
        int colonAt = socketString.indexOf(":");
        ipString = socketString.substring(1, colonAt);
        return ipString;
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        super.userEventTriggered(ctx, evt);
        String socketString = ctx.channel().remoteAddress().toString();

        if (evt instanceof IdleStateEvent) {
            IdleStateEvent event = (IdleStateEvent) evt;
            if (event.state() == IdleState.READER_IDLE) {

                Log.e("TAG", "数据:" +"Client: "+socketString+" READER_IDLE 读超时");
                ctx.disconnect();
            } else if (event.state() == IdleState.WRITER_IDLE) {

                Log.e("TAG", "数据:" +"Client: "+socketString+" WRITER_IDLE 写超时");
                ctx.disconnect();
            } else if (event.state() == IdleState.ALL_IDLE) {

                Log.e("TAG", "数据:" +"Client: "+socketString+" ALL_IDLE 总超时");
                ctx.disconnect();
            }
        }



    }
}

发送数据

    try {
            RequestLanyaqueren requestLanyaqueren=new RequestLanyaqueren();
            requestLanyaqueren.setApi_name("bleCheckConfirm_req");
            requestLanyaqueren.setBleName("new");
            requestLanyaqueren.setSN("51653658");
            String tojson = JSONUtils.tojson(requestLanyaqueren);
            Channel firstOrNull =   NettyServer.getMap().get( "TEST");
            Log.e("TAG", "数据1111:" +firstOrNull);
            firstOrNull.writeAndFlush(Unpooled.copiedBuffer( tojson, CharsetUtil.UTF_8));
            fasong.setText("发送数据为:"+tojson);
        }catch (Exception e){
            Log.e("TAG", "数据:" +e);
            Toast.makeText(this, "请先连接", Toast.LENGTH_SHORT).show();
        }

启动项目

    new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    new NettyServer().bind(8080);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).start();

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值