Netty核心原理:一、基础入门-05:NettyServer收发数据

news2024/12/23 6:53:43

文章目录

  • 一、前言介绍
  • 二、代码实现
    • 2.1 工程结构
    • 2.2 Netty服务端收发数据实现
      • 2.2.1 服务端处理器
      • 2.2.2 通道初始化
      • 2.2.3 netty服务端
    • 2.3 单元测试

一、前言介绍

💡 介绍服务端接收数据后,通过 writeAndFlush 发送 ByteBuf 字节码向客户端传输信息。

因为我们使用客户端模拟器的编码是 GBK 格式,否则会乱码。

二、代码实现

2.1 工程结构

netty-1.0-05
|-src
    |-main
         |-java
             |-com.lino.netty.server
		            |-MyChannelInitializer.java
		            |-MyServerHandler.java
		            |-NettyServer.java

2.2 Netty服务端收发数据实现

2.2.1 服务端处理器

MyServerHandler.java

package com.lino.netty.server;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.socket.SocketChannel;
import java.time.LocalDateTime;
import java.util.Date;

/**
 * @description: 服务端处理器
 */
public class MyServerHandler extends ChannelInboundHandlerAdapter {

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        SocketChannel channel = (SocketChannel) ctx.channel();
        System.out.println("链接报告开始");
        System.out.println("链接报告信息:有一客户端链接到本服务端");
        System.out.println("链接报告IP:" + channel.localAddress().getHostString());
        System.out.println("链接报告Port:" + channel.localAddress().getPort());
        System.out.println("链接报告完毕");
        // 通知客户端连接建立成功
        String str = "通知客户端链接建立成功" + " " + new Date() + " " + channel.localAddress().getHostString() + "\r\n";
        ByteBuf buf = Unpooled.buffer(str.getBytes().length);
        buf.writeBytes(str.getBytes("GBK"));
        ctx.writeAndFlush(buf);
    }

    /**
     * 当客户端主动断开服务端的链接后,这个通道就是不活跃的。
     * 也就是说客户端与服务端的关闭了通信通道并且不可以传输数据。
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("客户端断开链接" + ctx.channel().localAddress().toString());
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        // 接收msg消息
        System.out.println(LocalDateTime.now() + " 接收到消息:" + msg);
        // 通知客户端链接消息发送成功
        String str = "服务端收到:" + new Date() + " " + msg + "\r\n";
        ByteBuf buf = Unpooled.buffer(str.getBytes().length);
        buf.writeBytes(str.getBytes("GBK"));
        ctx.writeAndFlush(buf);
    }

    /**
     * 抓住异常,当发生异常的时候,可以做一些相应的处理,比如打印日志、关闭链接
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        ctx.close();
        System.out.println("异常信息:\r\n" + cause.getMessage());
    }
}

2.2.2 通道初始化

MyChannelInitializer.java

package com.lino.netty.server;

import io.netty.channel.ChannelInitializer;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.LineBasedFrameDecoder;
import io.netty.handler.codec.string.StringDecoder;
import java.nio.charset.Charset;

/**
 * @description: 通道初始化
 */
public class MyChannelInitializer extends ChannelInitializer<SocketChannel> {

    @Override
    protected void initChannel(SocketChannel channel) {
        // 解码转String,注意调整自己的编码格式 GBK,UTF-8
        channel.pipeline().addLast(new StringDecoder(Charset.forName("GBK")));
        // 在管道中添加接收数据实现方法
        channel.pipeline().addLast(new MyServerHandler());
    }
}

2.2.3 netty服务端

NettyServer.java

package com.lino.netty.server;

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

/**
 * @description: netty服务端
 */
public class NettyServer {

    public static void main(String[] args) {
        new NettyServer().bind(7397);
    }

    /**
     * 开启链接
     *
     * @param port 端口
     */
    private void bind(int port) {
        // 配置服务端NIO线程组
        // NioEventLoopGroup extends MultithreadEventLoopGroup
        // Math.max(1, SystemPropertyUtil.getInt("io.netty.eventLoopThreads", NettyRuntime.availableProcessors() * 2));
        EventLoopGroup parentGroup = new NioEventLoopGroup();
        EventLoopGroup childGroup = new NioEventLoopGroup();
        try {
            ServerBootstrap b = new ServerBootstrap();
            b.group(parentGroup, childGroup)
                    // 非阻塞模式
                    .channel(NioServerSocketChannel.class)
                    .option(ChannelOption.SO_BACKLOG, 128)
                    .childHandler(new MyChannelInitializer());
            ChannelFuture future = b.bind(port).sync();
            System.out.println("lino-learn-netty server start done.");
            future.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            childGroup.shutdownGracefully();
            parentGroup.shutdownGracefully();
        }

    }
}

2.3 单元测试

启动NettyServer

lino-learn-netty server start done.
链接报告开始
链接报告信息:有一客户端链接到本服务端
链接报告IP192.168.80.1
链接报告Port7397
链接报告完毕
2023-02-18T14:32:51.321 接收到消息:你好,netty服务端!
2023-02-18T14:32:52.063 接收到消息:你好,netty服务端!
2023-02-18T14:32:52.607 接收到消息:你好,netty服务端!
2023-02-18T14:32:53.391 接收到消息:你好,netty服务端!
客户端断开链接/192.168.80.1:7397

网络调试助手

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1000330.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【动态规划】01背包问题

文章目录 动态规划&#xff08;背包问题&#xff09;1. 01背包2. 分割等和子集3. 目标和4. 最后一块石头的重量 || 动态规划&#xff08;背包问题&#xff09; 1. 01背包 题目链接 状态表示 dp[i][j] 表示从前i个物品当中挑选&#xff0c;总体积不超过j,所有选法当中能挑选出…

【码银送书第六期】《ChatGPT原理与实战:大型语言模型的算法、技术和私有化》

写在前面 2022年11月30日&#xff0c;ChatGPT模型问世后&#xff0c;立刻在全球范围内掀起了轩然大波。无论AI从业者还是非从业者&#xff0c;都在热议ChatGPT极具冲击力的交互体验和惊人的生成内容。这使得广大群众重新认识到人工智能的潜力和价值。对于AI从业者来说&#xf…

腾讯云4核8G12M带宽服务器支持多少人同时在线?

腾讯云轻量4核8G12M服务器配置446元一年&#xff0c;518元12个月&#xff0c;腾讯云轻量应用服务器具有100%CPU性能&#xff0c;系统盘为180GB SSD盘&#xff0c;12M带宽下载速度1536KB/秒&#xff0c;月流量2000GB&#xff0c;折合每天66.6GB流量&#xff0c;超出月流量包的流…

JavaScript学习--Day04

元字符 边界符&#xff1a; /^/&#xff1a;以什么开头 /$/&#xff1a;以什么结尾 量词&#xff1a; 预定义类&#xff1a;

用hadoop-eclipse-plugins-2.6.0来配置hadoop-3.3.6

hadoop-eclipse-plugins这个插件是Eclipse中Hadoop的插件&#xff0c;但在寻找这个插件的过程中&#xff0c;突然发现插件的版本最好与hadoop的版本的一样 但我所能找到的最新版是3.3.1的&#xff0c;试了试&#xff0c;运行有问题&#xff0c;不能用 然后又试了试自己搭对应…

PIGOSS BSM:网络大屏展现功能与特色全面解析

导语 PIGOSS BSM是一款强大的IT运维监控工具&#xff0c;提供了丰富的功能和特色。其中的“网络大屏”模块是其核心功能之一&#xff0c;能够以直观、全面的方式展示网络设备的状态信息和各种关键指标。本文将详细介绍PIGOSS BSM网络大屏的功能及特色&#xff0c;让您全面了解其…

Swift学习内容精选(一)

Swift 可选(Optionals)类型 Swift 的可选&#xff08;Optional&#xff09;类型&#xff0c;用于处理值缺失的情况。可选表示"那儿有一个值&#xff0c;并且它等于 x "或者"那儿没有值"。 Swfit语言定义后缀&#xff1f;作为命名类型Optional的简写&…

vue3项目应用font awesome6

element-plus框架的图标icon种类较少&#xff0c;一般无法涵盖所有业务情况 这时候引入font awesome6免费版&#xff0c;图标库非常丰富&#xff0c;一般可以满足所有业务场景 官网&#xff1a;https://fa6.dashgame.com/Font Awesome 6&#xff0c;一套始终绝佳的图标字体库…

快速排序(重点)

前言 快排是一种比较重要的排序算法&#xff0c;他的思想有时候会作用到个别算法提上&#xff0c;公司招聘的笔试上有时候也有他的过程推导题&#xff0c;所以搞懂快排势在必行&#xff01;&#xff01;&#xff01; 快速排序 基本思想&#xff1a; 根据基准&#xff0c;将数…

深度学习实战52-基于医疗大模型与医疗智能诊断问答的运用研究

大家好,我是微学AI,今天给大家介绍一下深度学习实战52-基于医疗大模型与医疗智能诊断问答的运用研究。医疗大模型通过收集和分析大量的医学数据和临床信息,可以辅助医生进行疾病诊断、治疗方案制定和预后评估等工作。利用医疗大模型,可以帮助医生从复杂的医学数据中提取有价…

【记一次vsan数据救援的经历】

记一次vsan数据救援的经历 1. 背景2. 事情起因&#xff1a;以下是他自述详细操作步骤&#xff1a; 事前盘点&#xff1a;救援前分析与安排第一阶段工作&#xff1a;第二阶段工作&#xff1a;针对不可访问对象分的救援阶段阶段一 &#xff1a;学习vsan 知识&#xff0c;并检查当…

CCOS 2023 | 周进院长出席会议并于多个分会场担任讲者

9月6-10日&#xff0c;由中华医学会、中华医学会眼科学分会主办&#xff0c;湖南省医学会、湖南省医学会眼科学专业委员会承办的第二十七次全国眼科学术大会(CCOS2023)将在长沙国际会议中心和长沙国际会展中心举行。 此次大会以“凝聚高质量发展共识 共筑新时代光明未来”为主题…

人工智能AI 全栈体系(一)

第一章 神经网络是如何实现的 这些年人工智能蓬勃发展&#xff0c;在语音识别、图像识别、自然语言处理等多个领域得到了很好的应用。推动这波人工智能浪潮的无疑是深度学习。所谓的深度学习实际上就是多层神经网络&#xff0c;至少到目前为止&#xff0c;深度学习基本上是用神…

Keepalived编译安装报错处理记录

一、背景 因国产化OS改造&#xff0c;对Keepalived迁移重新部署&#xff0c;现场版本比较老&#xff0c;采用2.0.6版本&#xff0c;本次迁移&#xff0c;只迁移配置文件和自启动服务&#xff1b;其他考虑环境依赖&#xff0c;在目标OS上重新编译安装。 资源链接&#xff1a;o…

数据结构题型1--头插法建立单链表

下面是可运行的代码 #include <iostream> //引入头文件 using namespace std;typedef int Elemtype;#define Maxsize 100 #define ERROR 0 #define OK 1typedef struct LNode {Elemtype data;//数据域struct LNode* next;//指针域 }LNode,* LinkList;bool InitList(…

MyBatis: 插件是怎么起作用的?

示例&#xff1a; 假如配置了PageHelper插件 public class MyBatisTest10 {public static void main(String[] args) throws IOException {SqlSessionFactory sqlSessionFactory new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.x…

iOS开发Swift-11-正向传值,搜索,反向传值,城市id获取天气,光标聚焦,拦截空白/空格字符-和风天气App次页代码

1.创建次页的controller class 在Main中选择次界面,点击左上方黄色的圈圈,将它的Custom Class中的class修改为QueryViewController. 将QueryViewController中自动生成的首页传值方法复制到ViewController中去.去掉注释符号. 2.在Main中给1页向2页传值的箭头命名为QueryVi…

怎么在树莓派上搭建WordPress博客网站,并发布到外网可访问?

文章目录 序幕概述1. 安装 PHP2. 安装MySQL数据库3. 安装 Wordpress4. 设置您的 WordPress 数据库设置 MySQL/MariaDB创建 WordPress 数据库 5. WordPress configuration6. 将WordPress站点发布到公网安装相对URL插件修改config.php配置 7. 支持好友链接样式8. 定制主题 序幕 …

msvcp100.dll缺失的处理方法,4个修复msvcp100.dll的技巧

其实只要是经常使用电脑的人&#xff0c;那么迟早会遇到一个问题&#xff0c;那就是dll文件的丢失&#xff0c;它会提示你的电脑缺失了某某dll文件&#xff0c;如msvcp100.dll找不到&#xff0c;msvcp100.dll缺失等等&#xff0c;今天我们主要来讲一下&#xff0c;万一你的电脑…

车间作业分析重点分析的内容是哪些?

我们通常所说的车间作业分析&#xff0c;就是为提高作业效率和消除浪费而充分了解作业内容的构成因素和区分作业&#xff0c;并了解其组合是否有浪费现象&#xff0c;为提高分析要素作业的方法。 经过作业分析&#xff0c;可以查漏补缺&#xff0c;能发现平时正常作业时不易觉察…