netty学习之netty使用和流程分析

本文详细介绍了TCP的粘包和拆包现象,以及Netty如何通过上层协议处理这些问题,包括使用定长消息、添加边界、消息头等方式。此外,还深入分析了Netty服务端和客户端的创建流程,涉及ServerBootStrap、EventLoopGroup、ChannelPipeline和ChannelHandler等关键组件的作用。
摘要由CSDN通过智能技术生成

一、TCP的粘包和拆包

TCP协议数据传输是一个无界的数据流,而我们的请求数据确有多有少,所以会出现一次请求数据过多在TCP传输过程中会发送两个包 这种现象称之为拆包,同理粘包是多个请求作为一个TCP数据包传输给服务端。

如下例子:客户端发送两个请求

请添加图片描述

产生的原因

  1. 应用程序write字节大小 大于TCP发送缓存区大小
  2. TCP请求数据大于MSS的设置(MSS是TCP报文负载的最大长度),需要进行TCP分段发送。

那么怎么解决TCP的粘包和拆包的呢?

​ 底层的TCP无法理解上层业务数据,所以在底层无法保证数据不被拆分或者重组,只能通过上层协议来进行处理,如下常用的几种方式

  1. 消息定长,不足的空位补充

  2. 消息之间添加边界,比如特殊字符

  3. 消息使用消息头,头部包含消息的字段长度。

  4. 使用更复杂的应用协议。

二、复现粘包、拆包问题

2.1、目录结构

   下面我们来看看netty例子出现的粘包拆包(同时也是netty使用的例子学习)gitee地址:[netty学习项目](https://gitee.com/xieqx_79/netty-study.git)  

module: netty-one
项目结构如下: 请添加图片描述
相关类说明

  • NettyServer: netty服务端
  • NettyServerHandler netty服务端读写消息处理器
  • NettyClient: netty客户端
  • NettyClientHandler netty客户端读写消息处理器

2.2、netty服务端

NettyServer

public class NettyServer extends ChannelInitializer {
   

    public void start(Integer port){
   
        //客户端连接NIO线程组
        NioEventLoopGroup bossGroup = new NioEventLoopGroup();
        //用户处理读写请求的NIO线程组
        NioEventLoopGroup workerGroup = new NioEventLoopGroup();
        //NIO服务启动辅助类
        ServerBootstrap bootstrap = new ServerBootstrap();
        //添加线程池组 添加两个线程池组(一个线程池组用于处理客户端连接,一个线程池组用户处理读写消息)
        bootstrap.group(bossGroup,workerGroup)
                //添加处理读写的通道
                .channel(NioServerSocketChannel.class)
                //设置服务端TCP参数 SO_BACKLOG表示和该服务端连接的客户端最大数量
                .option(ChannelOption.SO_BACKLOG,1024)
                //添加相关处理器(最终组成处理器链对请求进行处理)通过ChannelPipeline添加ChannelHandler
                .childHandler(this);

        try {
   
            //绑定端口
            ChannelFuture sync = bootstrap.bind(port).sync();
            //服务监听端口关闭
            sync.channel().closeFuture().sync();
        } catch (InterruptedException e) {
   
            e.printStackTrace();
        }finally {
   
            //关闭线程组
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }

    }
    /**
     *初始化 为Channel通道的添加相关处理器 处理网络I/O事件
     */
    @Override
    protected void initChannel(Channel channel) throws Exception {
   
 
  • 10
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 14
    评论
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值