Linux网络之UDP与TCP协议详解

devtools/2024/9/24 7:07:44/

文章目录

    • UDP协议
      • UDP协议数据报
      • 报头
    • TCP协议
      • 确认应答
        • 缓冲区
      • 超时重传
      • 三次握手
        • 其他问题
      • 四次挥手
      • 滑动窗口
      • 流量控制
      • 拥塞控制

UDP协议

前面我们只是说了UDP协议的用法,但是并没有涉及到UDP协议的原理

毕竟知道冰箱的用法和知道冰箱的原理是两个层级的事情

我们首先知道计算机网络世界是搭建在四层架构上的

而HTTP协议是处于最顶层,是应用层协议,应用层协议的最大特点就是非常多,而且各异

这样多的协议要在网络中传输,必须得给他统一了,并且还能将底层收上来的数据,正确的交付到各个端口中

做到这些的就是传输层协议,主要有两个,就是大名鼎鼎的UDP和TCP

UDP协议数据报

所有的协议都规定了两部分,就是报头和数据本身,在传输层我们一般习惯把这整体称之为数据包

报头

在这里插入图片描述

报头是这样的

相比于IP协议和TCP协议,UDP协议的报头还是十分友好的

UDP的报头大小是固定的,8字节,因此当我们获取到一个UDP数据报之后,取前8个字节,找到UDP数据报的总长度,就能完整的取到整个报文数据

需要注意的是,16位UDP长度指的是UDP数据报的总长度,包含报头和数据部分,因此UDP的最大数据大小就是2^16-1,大小就是64KB

UDP的传输过程是不可靠的,无连接的,面向数据报,在我们之前介绍的时候有说过,他的主要应用场景其实就是直播了

TCP协议

在这里插入图片描述

TCP报头就比UDP丑多了,而且他还是不定长的,其中有一个交4位首部长度,是代表了TCP报头的大小,范围是20到60字节

其他的部分都是用来确保TCP的可靠性和效率所用到的

TCP如此知名,就是因为他的可靠性,那么他做了哪些事情保证他的可靠呢

确认应答

我们发出了一条信息,怎么确定对方是否看到了呢,在Line或者抖音中,会回显对方是否已读,这其实就是一个确认应答机制

为了保证可靠性,TCP协议规定了ACK机制,也就是确认应答机制

机智的朋友肯定发现上面的标志位中有一个ACK,就是用于这个事情的

在这里插入图片描述

但是如果服务器和客户机一人一条发送,服务器每发送一个数据,都要等客户端回答收到之后再发送,这样固然是可靠了,但是效率却也大大降低了

于是就有了下面的想法,一次发送10条数据,分别标记上1到10

客户端收到1回复2,表明自己的1收到了,下一个想要2,因此客户端在一次收到1到10之后会分别回复2到11

但是计算机网络纷繁复杂,数据报可不一定是按顺序到达的,这就麻烦了,我怎么知道我缺哪个呢,而且每一个都进行回复也太二了

然后我们再想,一次发送了1到10,但是接收到了,1到5,8到10,6和7都丢了

那我们只回复5,标识5以前的都正确收到了,接下来想要6

这样就好很多了

缓冲区

除此之外,TCP的协议是全双工的,用一个端口就可以执行发送和接收两个操作,而且系统调用recv和read也不是从网卡中读取数据到内存,而是从缓冲区里拿上来的,send和write其实也算写入到缓冲区的,不是直接写到网卡里

在这里插入图片描述

那这个缓冲区写满了怎么办,怎么知道,发送缓冲区没数据了怎么办

这其实就是那16位的窗口做的事情,他分别对应了缓冲区的大小,每一次收发其实都会把缓冲区的状态写在里面,当缓冲区都快满了,写方就知道不要再往里面传了

超时重传

当数据在传输过程中丢了怎么办,迟迟没有收到ACK就说明发送失败了

当服务器等了一段时间也没有收到客户机发来的ACK,就说明数据可能是丢了,无论是数据丢了,还是ACK丢了,都会触发超时重传

这时候TCP协议就会要求服务器重新传一次数据

一般来说这个一段时间其实是动态的,各家操作系统都是这样

逻辑是这样的500ms是一个单位,每次乘2,当次数有几次之后,就说明对方主机可能出毛病了,有可能是被拔网线了,这时候就不会重传了

其实TCP协议他可靠吗,确实,在他能做到的范围内确实可靠,但是如果被拔网线就没办法了(不可抗力)

三次握手

我们说TCP协议是面向连接的,这个连接是怎么建立的呢

就是通过三次握手,在TCP报头中的SYN标记就是标识我要跟你交朋友

过程是这样的

客户端发起请求,说,我要跟你做朋友(发送一个包含SYN标记的报文)

服务端收到之后,说,我收到了你的消息,我也要跟你做朋友(发送了一个ACK和SYN标记都有的报文)

客户端收到之后,说,好!(发送一个ACK标记的报文)

在这里插入图片描述

这三次数据传递其实就建立了一个TCP连接,但是建立连接的时候,是在哪一个动作呢

其实是在客户端最后一次发送之后,客户端就认为连接建立好了,而服务器接收到了之后,服务器就认为连接建立好了

接下来客户端就可以发送请求了,疯狂星期四,V我50

需要注意的是,服务器可不是一次只跟一个客户机聊天,说不定有成千上万的客户端来请求,而操作系统的管理策略其实就是先描述再组织,将这些连接管理起来

其他问题

有一个经典的面试问题为什么是三次握手,其他次数行不行

  1. 偶数次

这里需要知道一点,当我发出一条消息的时候,我是不知道这条消息能不能传达到的,但是可以确定的是,我之前的消息一定传到了,并且我也可以收到对方的消息

而在这个过程中,永远是客户机给服务器发送请求,如果是奇数次,说明最后一个确认是服务器发给客户端的,说明之前的信息都没问题了,为什么还要继续确认呢?我直接发我的请求不好吗

而且如果使用偶数次握手,是服务器先确认建立的连接,客户端就可以一直发送SYN报文,一直不建立连接,服务器需要面对的可就多了,维护连接过多可是会挂掉的

  1. 其他奇数次呢

1次就不说了太蠢了,5次以上那不就是浪费资源了

3次就能干好的事情为什么要5次7次,那不是脱裤子放屁吗

四次挥手

有资源的申请就要有资源的释放,有链接的申请就要有链接的释放

在TCP报头中有一个叫做FIN,其实就是final,标志着我要离开我的朋友了

链接的释放可以说客户端也可以是服务器,这里我为了方便表示说是客户端,表示我要的资源已经拿到了,要拜拜了

客户端发出请求,要拜拜了(发送一个带有FIN的报文)

服务器收到了,我知道了(原地等待一会儿)(返回一个ACK,表示我知道了,然后等待一个CLOSE_WAIT的时间,给客户机反悔的机会,看客户机还有没有别的话说)

这段时间服务器什么也没有等到,服务器说,这是我跟你说的最后一句话,以后再也没有了(假),拜拜(发送了一个LAST_ACK,表示最后一个ACK报文,并且附带了FIN标志,表示结束)

当客户端收到之后,其实连接就已经断开了,并且会维持一段时间TIME_WAIT,不让客户端对同一个端口发送请求,咱不能抓着一只羊薅羊毛吧

在这里插入图片描述

滑动窗口

如果服务器发送了1到20号数据,但是客户端收到的是1和3到20,只发了一个2的请求,服务器看到之后觉得他只收到了1,于是把2到20又发了一遍,这样的效率又变得不行了

于是就有了滑动窗口,我们把发送缓冲区和接收缓冲区想象成数组,儿窗口限制的其实是左右的下标,我们每次只确认窗口中的数据即可

在这里插入图片描述

在这里插入图片描述

需要注意的是,在滑动窗口中的每一个部分其实都是需要确认ACK的,这是和之前不一样的

流量控制

流量控制其实用到的原理就是上面的滑动窗口,我们需要控制发送数据的速度,不能让接收端的缓冲区过满,不然就是无用功了

这时候TCP报头中的显示缓冲区情况就起到作用了

拥塞控制

拥塞控制与流量控制不同,他是为了防止网络状况不好产生的原因,比如说路由器出问题,网络拥堵送不出去

TCP的解决方案是慢启动,他指的是一开始的发送的数据很少,但是是指数级别的增长

当这个增长达到一定阈值之后,就是用线性增长了,如果遇到了重传,就会减半


http://www.ppmy.cn/devtools/116381.html

相关文章

观成科技:新版suo5隧道工具加密流量跟踪分析

1、工具简介 suo5是一个高性能的http隧道代理工具,支持全双工半双工模式,具有很高的传输性能,现在越来越多的webshell管理工具与内存马生成工具都支持了生成suo5木马的功能。从v1.1.0版本开始,其TLS协议传输功能中,增…

Vue 3 中 `$emit` 的使用示例

在 Vue 3 中&#xff0c;$emit 用于子组件向父组件发送事件&#xff0c;这样父组件可以监听并响应子组件触发的事件。 1. 子组件示例&#xff1a;ChildComponent.vue <template><button click"handleClick">点击我</button> </template>&l…

跨站脚本攻击(XSS)

免责申明 本文仅是用于学习测试自己搭建的XSS注入漏洞使用,请勿用在非法途径上,若将其用于非法目的,所造成的一切后果由您自行承担,产生的一切风险和后果与笔者无关;本文开始前请认真详细学习《‌中华人民共和国网络安全法》‌及其所在国家地区相关法规内容【学法时习之丨…

ubuntu内网穿透后在公网使用ssh登录

需求&#xff1a; 我有一台内网可以通过ssh 22端口访问的设备操作系统是ubuntu server我还有1台拥有公网IP的服务器&#xff0c;IP地址是 6.66.666.6666我想随时从其他网段通过ssh访问我的ubuntu server设备 实现&#xff1a; 工具准备&#xff1a;frp 网址&#xff1a;https…

Python 复制Excel 中的行、列、单元格

在Excel中&#xff0c;复制行、列和单元格是日常工作中经常需要进行的操作&#xff0c;它可以帮助你快速调整数据布局、复制数据模板或进行数据的批量处理。 本文将详细介绍如何使用Python将Excel中的行、列、或单元格范围复制到指定位置。 所需Python库 要使用Python操作Exc…

得物App荣获新奖项,科技创新助力高质量发展

近日&#xff0c;备受瞩目的2024中国国际服务贸易交易会&#xff08;简称“服贸会”&#xff09;在北京盛大开幕&#xff0c;这一全球唯一的国家级、国际性、综合型服务贸易盛会再次汇聚了全球服务贸易领域的精英与前沿成果。服贸会由商务部和北京市政府携手打造&#xff0c;并…

flink 批量压缩redis集群 sink

idea maven依赖 <dependency> <groupId>org.apache.bahir</groupId> <artifactId>flink-connector-redis_2.11</artifactId> <version>1.0</version> </dependency> <dependency> <groupId>redis.clients</gr…

JDK7u21 HashMap版

今天在搞ROME HotSwappableTargetSource链的时候突然发现&#xff0c;JDK7U21反序列化链不仅HashMap.put触发了key.equals putForCreate也调用了 而且HashMap.readObject直接调用了putForCreate来还原 what?直接向HashMap两个put不就完了&#xff0c;还搞什么HashSet 开弄&am…