Netty一,Rest风格,Netty的Helloword、

2023-11-01

  • Rest风格,为一种编码风格。默认约定
    在这里插入图片描述
    在这里插入图片描述

NettyHelloword,客户端,和服务器端

  • 服务器端↓
package com.netty.c1;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringDecoder;

public class Hello {
    //服务器端代码
    public static void main(String[] args) {
//        1.启动器,负责组装netty组件,启动服务器
        new ServerBootstrap()
                //2.包含selector,检测io事件,可连接,可读可写等,+线程,简单理解,包含线程和选择器、
                .group(new NioEventLoopGroup())
                //3.选择一个ServerSocketChannel的实现。
                .channel(NioServerSocketChannel.class)
                //4.boss处理连接的,worker(child),负责读写的。决定worker(child)能干那些操作
                .childHandler(
                        //跟客户端连接后,和客户端进行数据读写的通道Initializer  初始化,负责添加别的Handler
                        new ChannelInitializer<NioSocketChannel>() {
                    @Override
                    protected void initChannel(NioSocketChannel ch) throws Exception {
//                        添加具体的Handler
                        ch.pipeline().addLast(new StringDecoder());//将byteBuf转为字符串
                        ch.pipeline().addLast(new ChannelInboundHandlerAdapter(){//自定义handler
                            @Override//读事件
                            //NioEventLoopGroup循环接收,当接收到的时候,初始化器会执行
                            public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
                                super.channelRead(ctx, msg);
                                //打印上一步转换好的字符串
                                System.out.println(msg);
                            }
                        });
                    }
                })
                .bind(8080);
    }

}


  • 客户端↓
package com.netty.c1;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringEncoder;

import java.net.InetSocketAddress;

public class HelloClient {
    public static void main(String[] args) {
        //创建启动器类。
        try {
            new Bootstrap()
            //添加选择器,Eventloop
                .group(new NioEventLoopGroup())
    //                选择客户端channe实现
            .channel(NioSocketChannel.class)
    //                添加处理器
            .handler(new ChannelInitializer<NioSocketChannel>() {
                @Override//在链接调用后被调用,初始化作用
                protected void initChannel(NioSocketChannel ch) throws Exception {
                    ch.pipeline().addLast(new StringEncoder());//把字符转编码成bytebuf发过去,服务器,吧ByteBuf解码成字符串
                }
            })
    //        链接到服务器
            .connect(new InetSocketAddress("localhost",8080))
            .sync()
            .channel()
            .writeAndFlush("hello word");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

Netty服务器端详解

package com.netty.c1;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;



public class Server {
    public static void main(String[] args) {
        EventLoopGroup bossGroup=new NioEventLoopGroup();//bossGroup用的是所以是ServerSocketChannel
        EventLoopGroup workerGroup=new NioEventLoopGroup();//workerGroup用的是所以是SocketChannel
        try {
            //创建服务器端启动对象
        ServerBootstrap bootstrap=new ServerBootstrap();
        bootstrap.group(bossGroup,workerGroup)
                .channel(NioServerSocketChannel.class)//因为是服务器端,所以是NioServerSocketChannel,客户端,没有Server
                .option(ChannelOption.SO_BACKLOG,128)//设置线程队列等待链接的个数
                .childOption(ChannelOption.SO_KEEPALIVE,true)//设置保持活动链接状态
                .childHandler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel ch) throws Exception {
                        //这里面的参数new ServerHandler(),为自己创建的类class,
                        ch.pipeline().addLast(new ServerHandler());
                    }
                });//设置处理器,因为是SocketChannel,所以是给workerGroup的

            System.out.println("服务器端ok" );
            try {
                //启动服务器并绑定端口
                ChannelFuture cf=bootstrap.bind(6668).sync();//绑定一个端口并同步, 生成一个ChannelFuture对象
                cf.channel().closeFuture().sync();//对关闭通道进行监听。
            } catch (InterruptedException e) {
                e.printStackTrace(); }
        }
        finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }


    }




}

package com.netty.c1;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.CharsetUtil;

import java.nio.ByteBuffer;

//继承Channel入栈适配器
//我们自定义一个handler,需要继承netty规定好的某个HandlerAdapter 适配器
//这时我们的handler才能称之为handler
public class ServerHandler extends ChannelInboundHandlerAdapter {
    @Override
    //读取实际数据,读取客户端发送的数据
    //ChannelHandlerContext含有1.管道pipline,通道,channel,地址等所有信息。
//    msg就是客户端发送的数据
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {

        System.out.println("Server,ChannelHandlerContext ctx=:"+ctx);
        //将msg转换为一个Bytebuf,是Netty的ByteBuf,性能更高。
        ByteBuf buffer=(ByteBuf) msg;
        System.out.println("msg:"+buffer.toString(CharsetUtil.UTF_8));
        System.out.println("客户端地址:"+ctx.channel().remoteAddress());
            }
    //数据读取完成后,进行的。
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {

        //把数据写到一个缓冲,同时刷新该缓冲区。是两个方法的合并。;一般情况下,对发送的数据进行编码
        ctx.writeAndFlush(Unpooled.copiedBuffer("服务器端发送 :hello 客户端",CharsetUtil.UTF_8));
    }
    //处理异常的,一般关闭通道
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {

        ctx.close();
    }
}

Netty客户端详解

package com.netty.c1;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;

public class Client {
    public static void main(String[] args)throws Exception
    {
        //客户端需要一个事件循环组。即可
        NioEventLoopGroup group = new NioEventLoopGroup();
        try {


        //创建一个客户端启动对象 助手
        //客户端使用的不是ServerBootstrap,而是Bootstrap
        Bootstrap bootstrap = new Bootstrap();
        //设置相关参数
        bootstrap.group(group)//设置线程组
                .channel(NioSocketChannel.class)//设置客户端通道的实现类。(反射)
                .handler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel socketChannel) throws Exception {
                        socketChannel.pipeline().addLast(new ClientHandler());//加入自己写的处理器
                    }
                });
        System.out.println("客户端ok" );
        //启动客户端,去连接服务器端,

        ChannelFuture channelFuture = bootstrap.connect("127.0.0.1", 6668).sync();
        //给关闭通道连接,进行监听
            channelFuture.channel().closeFuture().sync();
        }finally {
            group.shutdownGracefully();

        }
    }
}

package com.netty.c1;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.CharsetUtil;

import java.nio.ByteBuffer;

public class ClientHandler extends ChannelInboundHandlerAdapter {


    //当通道就绪就会触发
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("client"+ctx);
        ctx.writeAndFlush(Unpooled.copiedBuffer("hello server ,im Client", CharsetUtil.UTF_8));
    }   //当 通道有读取事件时,会触发。读取服务器端返回的数据



    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {

        ByteBuf buf=(ByteBuf) msg;
        System.out.println("服务器回复的消息"+buf.toString(CharsetUtil.UTF_8));
        System.out.println("服务器地址"+ctx.channel().remoteAddress());
    }
    //异常发生时
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
       cause.printStackTrace();
       ctx.close();
    }
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Netty一,Rest风格,Netty的Helloword、 的相关文章

  • 使用 objectGUID 进行查询 - Spring LDAP 模板

    我正在尝试获取 存储并依次使用 objectGUID 来查询 Active Directory 为了获取用户属性我正在使用以下 public static class MyDnKeyValueAttMapper implements Att
  • 哪个类调用了我的静态方法?

    假设我有一个带有静态方法的 Java 类 如下所示 class A static void foo Which class invoked me 进一步假设 A 类有任意数量的子类 class B extends A class C ext
  • 不同的 JDK 更新会产生不同的 Java 字节码吗?

    假设场景 我有一个项目 其源合规性级别指定为 1 5 现在 我使用两种不同的 JDK 编译此项目 首先使用 JDK 6 Update 7 然后使用 JDK 6 Update 20 这两个不同的 JDK 是否会生成不同的 Java 字节代码
  • 使用 Spring MVC 返回 PDF 文件

    实际上 我有这个功能 我有一个框架 可以在其中设置 URL ip port birt preview report report rptdesign format pdf parameters 并且该框架呈现 PDF 文件 但我想隐藏该网址
  • 按下按钮时清除编辑文本焦点并隐藏键盘

    我正在制作一个带有编辑文本和按钮的应用程序 当我在 edittext 中输入内容然后单击按钮时 我希望键盘和焦点在 edittext 上消失 但我似乎无法做到这一点 我在 XML 中插入了这两行代码 android focusable tr
  • 警告:跳过条目,因为它不是绝对 URI。 NetBeans 中的 GlassFish

    我成功安装了 GlassFish 但是 当我启动服务器时 我收到两条警告消息 警告 跳过条目 因为它不是绝对 URI 那是关于什么的 Launching GlassFish on Felix platform Aug 09 2014 10
  • 总结二维数组

    鉴于我当前的程序 我希望它在用户输入所有值后计算每列和每行的总和 我当前的代码似乎只是将数组的值加倍 这不是我想要做的 例如 如果用户输入具有以下值 1 2 3 2 3 4 3 4 5 的 3x3 矩阵 则看起来就像我在下面的程序中对其进行
  • Spring 术语中命令、表单、业务和实体对象之间的区别?

    我试图理解这些对象在松散耦合系统方面的差异 业务对象与实体对象相同吗 我可以使用 MVC 中的业务或实体对象作为我的命令对象吗 命令对象与表单对象相同吗 只是寻找 Spring 术语和用法中对象类型的说明 我在 stackoverflow
  • 将 EditText 聚焦在设备上运行的 PopupWindow 中时出现异常

    我正在为 Android 开发一个弹出窗口 它正在工作 我在上面添加了一个 EditText 和一个按钮 当在 ADV 上运行时 它可以正常工作 而在设备上运行时 当我专注于 EditText 时 这会抛出一个奇怪的异常 android v
  • 在 JavaFX 中拖动未装饰的舞台

    我希望将舞台设置为 未装饰 使其可拖动且可最小化 问题是我找不到这样做的方法 因为我遇到的示例是通过插入到主方法中的方法来实现的 我想通过控制器类中声明的方法来完成此操作 就像我如何使用下面的 WindowClose 方法来完成此操作 这是
  • java.lang.UnsupportedOperationException:无法解析索引 13 处的属性:TypedValue{t=0x2/d=0x7f010046 a=-1}

    我在 android attrs xml 文件中添加了一个用于不同色调的属性 在 styles xml 文件中 我为这些属性指定了颜色 因此每种样式的它们都不同 Attrs xml
  • java.lang.IllegalArgumentException:addChild:子名称“/”不唯一

    java lang IllegalArgumentException addChild 子名称 不唯一 通过在 tomcat webapps 文件夹中启用和禁用 saml 单点登录来替换现有 war 文件时遇到此问题 我正在使用 apach
  • Java中无参数的for循环

    我在看别人的代码 发现了这段代码 for 我不是 Java 专家 这行代码在做什么 起初 我认为这会创建一个无限循环 但在该程序员使用的同一个类中 while true 其中 如果我错了 请纠正我 是一个无限循环 这两个相同吗 为什么有人会
  • 使用 Java 通过 HTTP 下载未知长度的文件

    我想用java下载一个HTTP查询 但是我下载的文件在下载时有一个未确定的长度 我认为这将是相当标准的 所以我搜索并找到了它的代码片段 http snipplr com view 33805 http snipplr com view 33
  • 在Spring-Boot中,我们如何在同一个项目中连接两个数据库(Mysql数据库和MongoDB)?

    我正在尝试创建一个 Spring Boot 项目 其中我有一个要求 我想连接到不同的数据库 MySql 和 MongoDB 我是否需要做一些特殊的事情来连接到这两个数据库 或者 spring boot 会自动计算出自己连接到这两个数据库 我
  • java 1.8下无法启动eclipse

    java 1 8 升级后我无法启动 eclipse 附上错误截图 这是我的 eclipse 配置设置 我该如何解决 startup plugins org eclipse equinox launcher 1 3 0 v20120522 1
  • Apache HttpClient TCP Keep-Alive(套接字保持活动)

    我的 http 请求需要太多时间才能被服务器处理 大约 5 分钟 由于连接闲置 5 分钟 代理服务器将关闭连接 我正在尝试在 Apache DefaultHttpClient 中使用 TCP Keep Alive 来使连接长时间处于活动状态
  • Apache Kafka 是否提供异步订阅回调 API?

    我的项目正在将 Apache Kafka 视为老化的基于 JMS 的消息传递方法的潜在替代品 为了让这个过渡尽可能的顺利 如果替代的排队系统 Kafka 有一个异步订阅机制那就更理想了 类似于我们当前项目使用的JMS机制MessageLis
  • 升级到 Tomcat 8 时出现 ClassNotFoundException

    我最近将 NetBeans IDE 从 v7 3 升级到 v8 突然我的应用程序在连接到数据库时在服务器启动时抛出异常 这两个版本的 IDE 之间的唯一区别是后者使用 Tomcat 8 异常日志 javax naming NamingExc
  • 如何在 Servlet 中打开弹出窗口,然后重定向页面

    我想在调用 servlet 时打开一个弹出窗口 然后想将 servlet 重定向到某个 jsp page 这就是我所做的 protected void doGet HttpServletRequest request HttpServlet

随机推荐

  • 【算法】中序与后序遍历序列构造二叉树(二叉树、递归)

    106 从中序与后序遍历序列构造二叉树 根据一棵树的中序遍历与后序遍历构造二叉树 注意 你可以假设树中没有重复的元素 例如 给出中序遍历 inorder 9 3 15 20 7 后序遍历 postorder 9 15 7 20 3 返回如下
  • impala高级设置set之BATCH_SIZE

    官网地址 https impala apache org docs build html topics impala batch size html Number of rows evaluated at a time by SQL ope
  • [Python]考试应用界面和简单logo-学习笔记

    试题部分 list1 1 下列词语中划线字的读音完全正确的一组是 2 下列词语解释有错误的一组是 3 四川话中 瓜娃子 指的是 4 四川话中形容一个人是 干豇豆儿 是指这个人 5 四川话中 咔咔过过 是 6 妖精十怪 是 7 四川话中 呱迷
  • Mongodb 设置密码

    第一步 开机先 mongod dbpath 存放数据库文件夹路径 第二步 打开命令行窗口输入mongo 进入mongo环境 第三步 切换到 admin 数据库 use admin 第四步 给admin设置用户密码 user 用户名 pwd
  • 智能水位检测系统proteus_基于单片机控制的智能检测系统Proteus仿真设计研究

    0引言近年来 单片机发展到了一个全新阶段 广泛应用于电子 机械控制 自动化生产设计等行业 并逐步延伸到智能控制的诸多领域 以单片机为控制核心的小型自动化生产检测系统 尤其在一些液体产品的检测等复杂工程中 控制人员通过微处理单元对产品进行质量
  • mysql安装出现让输入根密码_MYSQL安装时解决要输入current root password的解决方法...

    在装MYSQL的时候发现要输入current root password不记得以前在电脑里装过 你的系统曾经装过MYSQL在重装就会要求输入原来设定的密码 如果是第一次安装就不会出现 在网上苦苦搜寻解决方法 终归结出以下解决方法 1 清除M
  • 牛逼,玩转 ChatGPT!

    ChatGPT是一种由OpenAI开发的人工智能模型 它可以模拟人类的对话交流 对话可以涉及各种话题 使用ChatGPT可以进行各种操作 例如自然语言生成 文本摘要 语言翻译 文本分类 问答系统等 下面是ChatGPT网站的可用链接 由于网
  • MySQL中存储过程与函数总结

    目录 1 存储过程与函数的概念 2 创建存储过程与函数 2 1 参数列表 3 使用变量 4 定义条件与处理程序 1 定义条件 2 定义处理程序 3 六种定义处理程序的方法 方法一 捕获sqlstate value 方法二 捕获mysql e
  • 介绍一种门限SM2密码方案

    中科院信息工程研究所的科研人员林璟锵 马原 荆继武等设计了一种 SM2 门限密码算法实现方案 他们在 2014 年 8 月向国家知识产权局提交了专利申请 名称是 适用于云计算的基于SM2算法的签名及解密方法和系统 授权公告号是 CN 104
  • 一念天堂

    一念成佛 一念成魔 很多事情就发生在一念之间 很多误会也发生在想说没说出口的一瞬间 虽然误会可能解开 但再也回不回从前 心安在这里给大家讲个故事 也算是给自己提个醒 该说的话一定要说出来 你不说别人永远都不知道 不该说的尽量别说 别人会误会
  • lua协程

    coroution协程 定义协程函数 co coroutine create function a b end 启动协程函数和继续运行 coroutine resume co 10 20 co coroutine wrap function
  • C++&QT实现计算器图形界面交互

    一 实验目的和要求 要求 在实验 03 实验 05的作业内容基础上 1 增加图形交互功能 2 增加3个逻辑运算符 并能处理逻辑运算符和算术运算符的混合运算 3 增加容错功能 能进行异常处理 说明 1 其中牵涉到数据结构相关的可复用代码 可自
  • C++实现——杨辉三角

    打印杨辉三角 include
  • k8s健康检查配置yaml文件编写

    1 就绪检测 apiVersion v1 kind Pod metadata name readiness httpget pod namespace default 放在那个空间下 spec ontainers name readines
  • 如何模拟编写MyBatis之DataSource与Session呢?

    转自 如何模拟编写MyBatis之DataSource与Session呢 下文笔者讲述mybatis之模拟DateSource和Session的方法分享 如下所示 DataSource和Session简介 DataSource 实现标准的j
  • linux sudo命令全称,linux sudo命令的概念与使用

    1 sudo介绍本文引用地址 http www eepw com cn article 201610 305498 htm sudo是linux下常用的允许普通用户使用超级用户权限的工具 允许系统管理员让普通用户执行一些或者全部的root命
  • Docker 之 RUN

    参考 https docs docker com engine reference builder run RUN 有两种形式 RUN
  • python中round(x、2)是什么意思_python中round函数具体使用详解

    round函数是python中的内置函数 它在哪都能用 用于数字的四舍五入 当指定的位数大于 0 返回四舍五入到指定的小数位 当指定的位数等于 0 返回四舍五入到最接近的整数 保留整数部分 当指定的位数小于 0 对整数部分进行四舍五入 返回
  • Go读取Xml标签数据

    目录 目录结构 xzm xml文件 readMysqlXml go代码 效果展示 作者留言 目录结构 xzm xml文件
  • Netty一,Rest风格,Netty的Helloword、

    Rest风格 为一种编码风格 默认约定 NettyHelloword 客户端 和服务器端 服务器端 package com netty c1 import io netty bootstrap ServerBootstrap import