✨计算机网络—网络原理之TCP协议
作者介绍:
作者:偷偷敲代码的青花瓷
作者的Gitee:代码仓库
系列文章推荐:
✨1.计算机网络 ——网络原理之初识
✨2.计算机网络—网络编程套接字之UDP数据报套接字编程
✨3.计算机网络 — 网络编程套接字之TCP套接字编程
✨✨我和大家一样都是热爱编程✨,很高兴能在此和大家分享知识,希望在分享知识的同时,能和大家一起共同进步,取得好成绩,今天和大家分享的章节是计算机网络—网络原理之TCP/IP协议,如果有错误❌,欢迎指正哟,咋们废话不多说,跟紧步伐,开始学习吧~
文章目录
- 1. 应用层
- 常见应用层协议以及区别
- 2. 传输层
- 2.1 UDP协议
- UDP的特点
- 2.2 TCP协议
- 3. TCP协议的主要机制
- 3.1 确认应答(ACK)机制
- 3.2 超时重传机制
- TCP内部去重
- 3.3 连接管理机制
- 如何建立连接:三次握手
- 经典面试题
- 如何断开连接:四次挥手
- 3.4 TCP协议中的状态
- 3.5 滑动窗口机制
- 丢包如何处理
- 3.6 流量控制
- 3.7 拥塞控制
- 3.8 延迟应答
- 3.9 捎带应答
- 3.10 面向字节流=>粘包问题
- 3.11 TCP异常情况
- 面试题:
- 如何基于UDP协议实现可靠传输?
- 啥样的场景中适合使用TCP,啥样的场景中适合使用UDP
- 总结
应用层协议包含两个工作:1.明确传输信息 2.明确数据的组合格式
常见的应用层协议:
xml
json
protobutter
HTTP
xml:比较老牌的数据格式:可读性高,运行效率不行
<标签名>内容<标签名>
json:可读性高,运行效率不行
HTTP:当前最出名的应用层协议
传输层和网络层是
操作系统内核实现好的
,普通程序猿不能修改
核心功能:完成"端对端"的数据传输
传输层协议有很多,最常用的两个:UDP和TCP
无连接
:知道对端的IP和端口号就直接进行传输, 不需要建立连接
不可靠
:没有确认机制, 没有重传机制
; 如果因为网络故障该段无法发到对方, UDP协议层也不 会给应用层返回任何错误信息
面向数据报
: 不能够灵活的控制读写数据的次数和数量
面向数据报:
应用层交给UDP多长的报文, UDP原样发送,
既不会拆分, 也不会合并
UDP缓冲区:
1.UDP没有真正意义上的发送缓冲区. 调用sendto会
直接交给内核
, 由内核将数据传给网络层协议进行后续的传输动作
2.UDP具有接收缓冲区. 但是这个接收缓冲区不能保证收到的UDP报的顺序和发送UDP报的顺序一致
; 如果缓冲区满了, 再到达的UDP数据就会被丢弃
3.UDP的socket既能读, 也能写, 这个概念叫做全双工
UDP使用注意事项:
我们注意到, UDP协议首部中有一个16位的最大长度. 也就是说一个UDP能传输的数据最大长度是64K(包含UDP首部). 然而64K在当今的互联网环境下, 是一个非常小的数字. 如果我们需要传输的数据超过64K, 就需要在应用层手动的分包, 多次发送, 并在接收端手动拼装
TCP全称为 “传输控制协议(Transmission Control Protocol”). 人如其名, 要对数据的传输进行一个详细的控制
TCP是一个非常重要的协议,不光在实际开发中广泛使用,同时也是面试中的高频问题
确认应答:
保证可靠传输的核心机制
,关键就是接收方收到消息之后,给发送方返回一个应答报文(ACK)表示自己收到了
序号和确认序号:
TCP将
每个字节的数据
都进行了编号,即为序号
每一个ACK都带有对应的确认序号
,意思是告诉发送者,我已经收到了哪些数据,下一次你从哪里开始发
相当于对
确认应答
进行了补充,确认应答是网络一切正常的时候,通过ACK通知发送方我收到了,如果出现了丢包的情况,超时重传机制就会起到效果
注意:
如果重传失败,可能还会再尝试,也不会无休止的重传,连续几次重传都不行,就认为这个网络可能是遇到了严重的情况,再怎么传都不行就只能放弃了
出现丢包的两种情况:
第一种:发出去的消息丢了
第二种:另外一种情况就是 ACK 丢了,虽然对方收到了消息,但是我收不到 ACK
如果是 ACK 丢了此时触发的超时重传,就会导致对方接收到重复的消息,TCP内部就会有一个去重操作,接收方接收到的数据先会放到操作系统内核的"接收缓冲区"中,接收缓冲区可以视为是一个
内存空间
,并且也可以视为是一个阻塞队列
收到新的数据,TCP就会根据序号,来检查这个数据是不是在接收缓冲区中已经存在了,如果不存在,就直接进去,如果存在直接丢弃,保证应用层序调用socket api 拿到的这个数据一定不是重复的。
基于上述:确认应答和超时重传两个机制,TCP的可靠性,得到了有效的保障
连接管理也是TCP保证可靠性的一个机制
,在正常情况下, TCP要经过三次握手建立连接, 四次挥手断开连接
三次握手客户端和服务器之间,通过三次交互,完成了建立连接的过程
,"握手"是一个形象的比喻
三次握手有什么用?和可靠性有什么关系?
三次握手相当于
投石问路
,检查当前这个网络的情况是否满足可靠传输的基本条件
更具体的说,可以认为三次握手其实也是在检测通信双方,发送能力和接受能力是否都正常
1.描述TCP三次握手的过程
上面已经详细给大家讲解了TCP三次握手的过程,这里不再详细说了,记住,以后面试的时候,画图!!!
2.为什么握手是三次?而不是两次?四次?
对于四次握手来说:
四次握手 行
,但是没必要,分开传输降低效率,不如合在一起
对于两次握手来说:两次握手 不行
,意味着缺少最后一次,此时客户端这边关于发送接收能力正常的情报是完整的,但是服务器这边是残缺的,服务器不知道自己的发送能力是否ok,也不知道客户端的接受能力是否ok,此时此刻,服务器相对于当下能否可靠传输,心里是没底的,这第三次交互,就是为了给服务器吃一个定心丸
滑动窗口存在的意义就是在保证可靠性的前提下,尽量提高传输效率
这样一发一收
的方式性能较低, 那么我们一次发送多条数据
, 就可以大大的提高性能(其实是将多个段 的等待时间重叠在一起了)
当前有一个核心问题:丢包,如果出现了丢包,如何进行重传?
情况一:ACK丢了
这种情况下, 部分ACK丢了并不要紧, 因为可以通过后续的ACK进行确认
情况二:数据丢了
这里的重传只是需要把丢了的那一块数据给重传了即可
,其他已经到了的数据就不必再重传了,整体的重传效率还是比较高的(快重传)
注意:
接收端处理数据的速度是有限的. 如果发送端发的太快, 导致接收端的缓冲区被打满, 这个时候如果发送端 继续发送, 就会造成丢包, 继而引起丢包重传等等一系列连锁反应
因此TCP支持根据接收端的处理能力, 来决定发送端的发送速度. 这个机制就叫做流量控制(Flow Control)(流量控制是滑动窗口的延伸,目的是为了保证可靠性)
举个例子:
流量控制:发送方先有一个初始的窗口大小,发送数据过去之后,对方返回一个 ACK,ACK 中除了有确认序号之外,还有一个数据,表示"接收方缓冲区的剩余空间大小"
接收方如何告知发送方,剩余空间多大?
拥塞控制也是滑动窗口的延伸,也是限制滑动窗口发送的速率
拥塞控制衡量的是:发送方接收方,这个链路之间,拥堵情况(处理能力)
如何限制滑动窗口发送的速率:
相当于流量控制的延伸,流量控制可以理解为刹车,使发送方,发的不要太快,延伸应答,就想在这个基础上,能够尽量的再让窗口更大一些
先画个图方便大家理解:
再举个通俗的例子:
比如老师催我做作业,老师看到我落下了10次作业…就给我发消息,说:你小子最近作业落下的有点多呀
我有两种回应方法:
1.立即回复(此时落下10次),我自知理亏,肯定会承认错误,并表示尽快来弥补
2.稍微晚一会回复,趁着这个时间,狂补作业,补到晚上的时候,补了7次,回复的时候就可以是说,老师你看错了,我只落下三次并不多
在延迟应答的基础上, 我们发现, 很多情况下, 客户端服务器在应用层也是 “一发一收” 的. 意味着客户端给 服务器说了 “How are you”, 服务器也会给客户端回一个 “Fine, thank you”
那么这个时候ACK就可以搭顺风车 , 和服务器回应的 “Fine, thank you” 一起回给客户端
客户端和服务器之间的通信,有以下几种模型:
1.
一问一答
:客户端发一个请求,服务器返回一个对应的响应
2.多问一答
:上传文件
3.一问多答
:下载文件
4.多问多答
:直播~~串流…
首先要明确, 粘包问题中的 "包" , 是指的应用层的数据包
TCP粘包指的是粘 的是应用层数据报
,在 TCP 接收缓冲区中,若干个 应用层数据包混在一起了,分不出来谁是谁
3.机器掉电/网线断开
这个题其实就是考TCP,本质上就是在应用层基于UDP复刻TCP的机制
实现确认应答机制
. 每个数据收到之后,都要反馈一个ACK(应用程序自己定义一个 ack包)
实现序号/确认序号,以及实现去重
实现超时重传
.
实现连接管理
要想提高效率,实现滑动窗口
为了限制滑动窗口,实现流量控制/拥塞控制
实现延时应答,捎带应答,心跳机制
…
1:啥时候使用TCP? =>对可靠性有一定要求,(日常开发中的大多数情况,都基于TCP)
2:如果传输的单个数据报比较长(超过 64k) -> 首选 TCP
3:啥时候使用UDP? =>对可靠性要求不高,对于效率的要求更高(机房内部的主机之间通信,分布式系统中,广播就是首选UDP)
“种一颗树最好的是十年前,其次就是现在”
所以,
“让我们一起努力吧,去奔赴更高更远的山海”
如果有错误❌,欢迎指正哟