当前位置:首页 > 服务端 > 从tcp到netty(一)

从tcp到netty(一)

2022年11月09日 21:58:35服务端6

  发现自己近一年有些毛病,自己也算是研习了不少的源代码,看了不少的技术书籍,但是自己就是记忆力不行,总是过段时间就会忘记,忘记之后还得从头开始啃源码、啃书籍。而且有些重要技术点也会遗忘,导致再学习的时候发现自己又回到了起点!我总结为,就是自己近一年期间犯懒,没有再写一下博客,技能点不能很好的再回顾!

  趁着发现自己的问题,同时自己也在做前后端rpc分离实践,现在将之前研习netty的结果再总结出来,写到博客上!

  首先,我们要确定java中的netty用来做什么的?具体的工作模式优势不解释,网上能找一大堆,主要讲它通信这块的rpc,高效稳定的协议栈绕不开tcp/ip协议!

  本来是不想记录tcp/ip的,这个实在是没有太多好说的,但是也发现虽然自己明白,有时候却也是会遗漏要点知识,所以也还是记录一下吧!

  似乎作为上层程序员只需要了解tcp的握手与挥手情况即可!

  首先要了解tcp/ip的头部结构

16位源端端口   |  16位目标端端口

32位序列号(发送端确认信息)

32位确认序号(服务端确认)

4位偏移量(每个数字表示1个4字节,所以最大表示15个4字节,也就是60字节)----

6位保留位(记不太清了)  | 标志位:包括6种报文段 urg、ack、rst、syn、fin、psh

16位校验和     |     16位紧急指针

16位窗口大小(用于tcp缓冲区的控制)

40位填充字段。

  我觉得挺容易理解的,作为通信双方必须知道相互的地址,所以要有源地址与目标地址的标记;序列号与确认序列号,这个涉及到数据包分片,比如mtu导致了数据分片,如何分片与如何重组分片;偏移数据表示tcp头部结构能够占用的最大数据长度;保留位大概就是保留用的吧;标记位,6个就是我们常说的同步报文段、确认报文段的标记;窗口大小表示一次传输数据的大小,由于是16位,按照二进制计算也就是65535字节;校验和据说是为了教研数据有效性的,我通过抓tcp的包看到类似这样的从tcp到netty(一) _ JavaClub全栈架构师技术笔记16位紧急指针,这个是配和urg报文段设置优先紧急数据的。

  然后是三次握手,与四次挥手中tcp状态的转移。都是基于上面tcp头部结构进行变化的。

三次握手

1):client将syn标志位置1,序列号seq置x(随机数), 发送到server端,client状态为同步发送状态,表示等待server端的确认;

2):server端收到client端数据包,判断syn=1,了解到为同步报文段。则这时,将要发送数据的tcp头部分别设置syn与ack为1,确认序列号x+1,序列号置y(随机数),发送到

  client端,server端状态为同步接收状态;

3):client端收到serve数据包之后,判断是否ack报文段为1,确认序列号是否为x+1,符合则将要发送的数据的tcp头部的ack报文段置1,确认序列号y+1,然后发送;到达server端

  之后,检查ack报文段是否为1 && 确认序列号是否为y+1,符合则建立连接。

  此时client与server都进入了建立成功阶段。

四次挥手

1): client将要发送报文信息的tcp头部的fin报文段置1,序列号置随机值x,发送给server端,client端状态为结束等待状态;

2): server端收到fin结束报文段,将发送报文信息的tcp头部ack置1,确认序号为x+1,server端进入关闭等待阶段;

3):server端再次发送一个报文数据,tcp头部fin置1,此时server端进入了最后确认阶段;

4):client接收到了server的ack报文信息与fin报文信息之后,验证确认序列号x+1,然后再向server端发送一个tcp头部ack=1的报文段,client进入time_wait阶段,server端收到信息

  验证后进入关闭状态;

最后的时刻client等待2*msl(最大报文传输时间)时间长度,进入close状态。

  第二绕不开的一点就是网络的io模型!一般我们应该都知道有几种常谈的io模型,阻塞式、非阻塞、异步io、多路复用、信号驱动的io模型,这里java常用的就是非阻塞式io与多路复用io也就是nio!nio基reactor的模型进行设计的。所以接下来要讲一下nio与reactor模型。

  Nio,这个我们需要去看epoll的解释,最好去看epoll的源码,这里我建议看一下深入理解nginx这本书中的epoll的解释,详细描述了代码状况!下面具体谈一下epoll的优秀思想设计。

  首先要知道原来模式的弊端,原有linux2.6之前的操作系统,采用select/poll的形式这两种形式在进行连接事件的收集的时候,是将所有活跃与不活跃的套接字由用户态的内存向操作系统的内核内存传递,然后由操作系统内核扫描所有套接字,不管是内存还是cpu都造成巨大的浪费。而epoll则不是,它定义了一个文件系统,首先,调用epoll_create创建一个epoll对象;然后,调用epoll_ctl向epoll添加所有的连接套接字;第三,调用epoll_wait收集活跃的连接这样它就避免了完全的内存复制,只进行收集活跃连接,然后也不用遍历原来所有的连接,使cpu也降温。

  Eventpoll是创建epoll时候的数据结构,里面是一种红黑树的数据结构,用于存储epoll_ctl向epoll对象中添加的事件,为什么使用红黑树,因为如果出现重复的套接字可以很快的识别出来。据书上说,被添加到epoll中的时间都会与网卡建立回调关系epoll_callback。Eventpoll中含有一个红黑树的根节点rbr与双向链表rdllist,回调事件会放到rdllist,所以epoll_wait扫描事件连接的时候就只针对这个rdllist的链表进行遍历,然后将事件复制给用户内存,所以也就保证了效率。

  第三,Reactor模式(也有人叫做反应器模式)!Netty中的nio线程模型命名了三种模式:Reactor单线程模型、Reactor多线程模型和主从多线程模型!实际上都是根据上边epoll的三阶段进行的划分,所以抽象出这三种阶段才能更好的理解这三种设计的模型,也就是得理解epoll的三种事件!所有这三种模型都是围绕着三种阶段进行的。

  单线程模型:就是说把这三个阶段统统放在一个线程上操作。该线程负责,创建事件对象,accept收集活跃socket,分发器分发二进制消息进行读写操作(接收数据、发送数据)。

  多线程模型:这个其实主要是将收集活跃的socket与事件分发分成了两步;一个专门的线程用于收集活跃的socket,另一个线程池专门负责数据的读写操作;

  主从多线程模型:这个其实是在多线程模型上进一步的加固;用来收集活跃socket的线程改成了线程池,acceptor接收到tcp socket接收验证(这个应该是指的tcp的数据验证)连接后,将该连接的通道交给io处理线程池的一个线程上进行io的读写操作。

  实际上就是这么回事,只是将原来串行的操作改成了并行化,同时保证线程的安全性!

作者:kevinfuture
来源链接:https://www.cnblogs.com/kevinfuture/p/8494648.html

版权声明:
1、JavaClub(https://www.javaclub.cn)以学习交流为目的,由作者投稿、网友推荐和小编整理收藏优秀的IT技术及相关内容,包括但不限于文字、图片、音频、视频、软件、程序等,其均来自互联网,本站不享有版权,版权归原作者所有。

2、本站提供的内容仅用于个人学习、研究或欣赏,以及其他非商业性或非盈利性用途,但同时应遵守著作权法及其他相关法律的规定,不得侵犯相关权利人及本网站的合法权利。
3、本网站内容原作者如不愿意在本网站刊登内容,请及时通知本站(javaclubcn@163.com),我们将第一时间核实后及时予以删除。


本文链接:https://www.javaclub.cn/server/69054.html

标签: Netty
分享给朋友:

“从tcp到netty(一)” 的相关文章

Android与Netty服务器连接

参考了:https://blog.csdn.net/yulinxx/article/details/51085782 首先服务器使用Netty框架搭建,关于Netty环境的搭建参考Netty环境搭建(Eclipse) Android客户端也采用了Netty框架,环境搭...

springcloud gateway nullpointerexception (NettyRoutingFilter)

springcloud gateway nullpointerexception (NettyRoutingFilter)

最近在做一个下载功能时,发现直接调用服务是可以下载的,但是通过gateway路由下载会报NPE异常,具体如下 java.lang.NullPointerException: null at java.util.concurrent.ConcurrentH...

http协议之请求方法、请求头、请求体分析和Netty解析

http协议之请求方法、请求头、请求体分析和Netty解析

请求报文 Http请求报文由三部分组成:请求行,请求头,请求体 携带信息 请求行:请求方法、请求地址、协议名称和版本号 请求头:Referer、User-Agent、Accept、Cookie、Cache-Control、Content...

Java 200+ 面试题补充② Netty 模块

Java 200+ 面试题补充② Netty 模块

让我们每天都能看到自己的进步。老王带你打造最全的 Java 面试清单,认真把一件事做到最好。 本文是前文《Java 最常见的 200+ 面试题》的第二个补充模块,第一模块为:《Java 200+ 面试题补充 ThreadLocal 模块》。 1.Netty...

Java高并发网络编程(五)Netty应用

Java高并发网络编程(五)Netty应用

推送系统   一、系统设计             二、拆包和粘包 粘包、拆包表现形式 现在假设客户端向服务端连续发送了两个数据包...

netty实现http客户端请求远程http服务

netty实现http客户端请求远程http服务

    一般http请求,我们会使用httpclient来实现连接池方式的连接,根据请求的类型,封装get,post等请求,设置参数,设置请求头,调用方法,发送请求之后等待请求返回结果,根据结果解析出我们需要的数据。netty也可以实现httpclient类似...

springboot整合netty(二)

springboot整合netty(二)

目录 前言 正文 代码 1. 新建一个springboot项目,在pom文件中添加netty依赖: 2.新建netty服务 3.netty调用...

netty的设计模式

如果要阅读源码,首先就要学会基本的设计模式。 设计模式是前人总结出来的软件设计方法,有利于使代码更加简洁优雅。 了解了netty的设计模式,再去看源码,会有一种焕然大悟的感觉。 一、单例模式 单例模式是最常见的设计模式: 1、忽略反射的影响,全局只有...

java netty rpc框架

java netty rpc框架

目录 第1篇 I/O基础篇 第1章 网络通信原理 1.1 网络基础架构 1.1.1 C/S架构 1.1.2 C/S信息传输流程 1.2 TCP/IP五层模型详解 1.2.1 物理层 1.2.2 数据链路层...

Netty通过Nginx配置 wss 协议访问(实践可行)

先写个比较简单的,后面再写一篇Vue + springboot +netty  Netty在互联网以及物联网公司用的很多,底层走的还是 websocket协议,好处很多,就不一一列了,相关的文章很多,大家可以搜下; 在实际开发应用中,基本上都是采用前后端分离...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。