传输层协议之TCP协议详解
传输层重点协议:UDP和TCP。
作用:负责数据能够从发送端传输到接收端。(在进行网络编程时,我们会使用到socket,然而一旦调用socket就进入到了传输层的范畴内)
前面我们已经讲过UDP协议了,这次我们来讲解什么是TCP协议,TCP协议有哪些特点。
TCP协议
传输控制协议(TCP,Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议。传输控制协议,顾名思义就是要对数据的传输进行一个详细的控制。
TCP协议段格式
源/目的端口号:表示数据是从哪个进程来的,要到哪个进程去
端口号:整数。0~65535之间的整数。
知名端口号:把0~1024这些端口号给具体划分了一些具体的作用。(80:http服务器;443:https服务器等)
32位序号/32位确认号:表示对接收到对方曾经发送过的TCP报文的确认
4位TCP报头长度:表示该TCP头部有多少个32位bit(有多少个4字节)。TCP报头的最大长度是15*4=60
6位标志位:(TCP报文的核心字段)
URG:紧急指针是否有效
ACK:确认号是否有效
PSH:提示接收端应用程序立刻从TCP缓冲区把数据读走
RST:对方要求重新建立连接;将携带RST标识的称为:复位报文段
SYN:请求建立连接;将携带SYN标识的称为:同步报文段
FIN:通知对方,本端将要关闭;将携带FIN标识的称为:结束报文段
16位窗口大小:保证TCP可靠性机制和效率提升机制的重要字段
6位保留字段:TCP报头中暂时未使用的6个比特位,不确定什么时候会用到
16位校验和:发送端填充,CRC校验。接收端校验不通过,则认为数据有问题。此处的校验和不光包含TCP首部,也包含TCP数据部分
16位紧急指针:标识哪部分数据是紧急数据
TCP如何将报头与有效载荷进行分离:
当我们获取到TCP报文后,首先对报文的前20个字节进行读取操作,同时从其中提取出4位的首部长度,此时就获得了TCP报头的长度大小,在读取完TCP的基本报头和选项字段后,剩下的就是该TCP报文的有效载荷了。
TCP原理
TCP对数据传输提供的管控机制,主要体现在两个方面:安全与效率。
这些机制的原则:保证数据传输安全的前提下,尽可能的提高传输效率。
安全机制
确认应答机制(安全机制)
确认应答机制是保证可靠传输的核心机制。
关键:接收方收到消息后,给发送方返回一个应答报文。
可靠指的是:发送方发送出数据后,能知道这个数据是否送到了,也就是说接收方是否收到了这个数据。
这是同一个TCP数据报,这个数据报通过层层封装,变成了一个以太网数据帧,然后进行传输。
数据(1~1000):A给B发送了1000个字节,序号是1~1000;
确认应答(下一个是1001):B给A返回的应答报文(ACK)就会带有一个确认序号叫做1001,表示下一次应该从1001开始发送了。
这样一来一回直到数据发送完毕。
TCP对每个字节的数据都进行了编号,这个编号我们称呼为“序列号”。
每一个ACK都带有对应的确认序列号,意思是告诉发送方,已经接收到了哪些数据,下一次该从哪里开始发送。
表示当前这个应答报文是针对哪个消息进行的确认应答。
关于序号和确认序号:
任何一条数据(包括应答报文)都是有序号的。
确认序号是只要应答报文有的(普通报文确认序号字段里的值是无意义的)。
先发后发的情况:如果传了多个数据报,分装成了多个以太网数据帧,多个数据帧之间才会出现先发后发的情况。
超时重传机制(安全机制)
相当于是对确认应答机制进行了补充。
确认应答是网络一切正常的时候,通过ACK通知发送方,我已经接收到了。如果出现了丢包的情况,超时重传机制就要发挥作用了。
主机A发送数据给B后,由于某些原因(网络拥堵等)数据无法到达主机B;
如果主机A在一个特定时间间隔内没有收到B发来的确认应答,就会进行重发。
主机A未收到主机B发来的确认应答还有一种情况:ACK丢了。
这种情况下,主机B会收到很多重复的数据。此时就需要TCP能够设别出哪些包是重复的包,并且将重复的包丢弃掉。
TCP内部有一个去重操作
接收方收到数据会先放到操作系统内核的“接收缓冲区”中,接收缓冲区可以视为是一个内存空间吗,也可以视为是一个阻塞队列。
收到新的数据报,TCP会根据序号来检查这个数据在接收缓冲区是否已经存在了,如果存在了,直接丢弃。如果不存在,就放进去。保证应用程序调用socket api拿到的这个数据一定是不重复的。
去重的问题,我们已经解决了。再考虑一下,如何确定这个超时的时间???
最理想状况下,找到一个最小的时间,保证“确认应答一定能在这个时间内返回”
这个时间的长短随着网络环境的不同是有差异的,如果设置的太长会影响整体重传的效率;设置的太短可能会频繁发送重复的包。
TCP为了保证无论在任何环境下都能有比较高校性能的通信,会动态计算这个最大超时时间。
在很多操作系统中(linux,windows和BSD unix),超时以500ms为有一个单位进行控制,每次判定重发的超时时间是以500ms的整数倍。如果重发一次仍没有应答,等待2*500ms后再进行重传。以此类推,以指数形式递增。
累计到一定的重传次数,TCP会认为网络或对端主机出现异常,强制关闭连接(自动断开TCP的连接)
超时重传的数据不一定能重传成功。
操作系统具体重传几次才放弃?操作系统超时时间每次增加多少??这些都是可以配置的。
连接管理机制(安全机制)
也是TCP保证可靠性的机制。描述了连接如何创建,又如何断开。
在正常情况下,TCP要经过三次握手建立连接,四次挥手断开连接。
此处对于三次握手四次挥手只是简单提到,后面会有单独讲解。
流量控制(安全机制)
关键:能够衡量接收方的处理速度。是滑动窗口的延申,目的是为了保证可靠性。
此处直接使用接收方接收缓冲区剩余空间的大小,来衡量当前的处理能力。
接收端处理数据的速度是有限的。如果发送端发送数据过快,那么就会导致接收端的缓冲区被充满,这时如果发送端继续发送数据,就会造成丢包,然后引起丢包重传等一系列连锁反应。
TCP支持根据接收端的处理能力,来决定发送端的发送速度。这个机制就叫做“流量控制”。
接收端将自己可以接入的缓冲区大小放入TCP首部中的“窗口大小”字段,通过ACK端通知发送端。
窗口大小字段越大,说明网络的吞吐量越高。
接收端一旦发现自己的缓冲区快满了,就会将窗口大小设置成一个更小的值,通知给发送端。
发送端接受到这个窗口后,就会减慢自己的发送速度。
如果接收端缓冲区满了,就会把窗口大小设置为0,这时发送端将不再发送数据,但是需要定期发送一个窗口探测数据段,使接收端把窗口大小告诉发送端。
接收方通过ACK报文中的16位窗口大小这个字段来告知发送方。
这个16位窗口大小字段是来衡量当前接收方剩余空间大小,发送方收到这个数据后,就会灵活的调整发送速度(调整窗口大小)
窗口探测报文不传输实际数据,只是为了触发ACK,只是为了知道当前的窗口大小是多少。
16位窗口大小字段的最大不止是65535字节,因为TCP首部40字节选项中还有一个窗口扩大因子M,实际窗口大小是窗口字段的值左移M位。
拥塞机制(安全机制)
也是滑动窗口的延申,也是限制滑动窗口发送的速率。
就是TCP协议像尽可能快的把数据传输给对方,但是又要避免给网络造成太大压力的折中方案。
拥塞控制衡量的是发送方到接收方这整个链路之间的拥堵情况(处理能力)。
如果当前的网络状态是比较拥堵的,在不清楚当前网络状态下,发送大量的数据,可能会引起网络拥堵情况更加严峻。
TCP引入慢启动机制,也就是说:先发送少量的数据探路,摸清楚当前的网络拥堵情况,再决定按照多大的速度传输数据。
最终滑动窗口的大小=min(拥塞窗口,流量控制窗口)。
这里引入一个新的概念:拥塞窗口
发送开始时,定义拥塞窗口大小为1
每次收到一个ACK应答,拥塞窗口加1
每次发送数据包时,将拥塞窗口和接收端主机反馈的窗口大小做比较,取较小值作为实际发送的窗口
为了不增长的太快,不能将拥塞窗口单纯的加倍。这里引入一个慢启动的阈值。当拥塞窗口超过这个阈值时,不再按照指数的方式增长,而是按照线性的方式增长。
当TCP开始启动时,慢启动阈值先是等于窗口的最大值,在每次超时重发时,慢启动阈值会变成原来的一半,同时拥塞窗口置为1.
当出现少量丢包时,仅仅是触发超时重传。当出现大量丢包时,就认为网络拥塞。
线性增长也是增长,增长到一定程度就会出现丢包,一旦丢包此时发送方立即就让窗口变小(回归初识的窗口大小),继续重复刚才的指数增长+线性增长的过程。
效率机制
滑动窗口(效率机制)
本质:批量的发送数据。
确认应答机制中,对于每一个发送的数据段都要给一个ACK确认应答。收到ACK后再发送下一个数据段。这样做的效率较差。针对这种问题,出现了滑动窗口。
一发一收的方式性能较低,我们一次性发送多条数据,就可以提高性能。一次发送一波数据,然后一起等待一波ACK。
并不是把N组数据的ACK都等到了才继续往下发送,而是收到一个ACK,就继续往下发送一组。
若当前是在等待1001,2001,3001,4001四组ACK,不用等4001到了才继续往下发。只要1001到了,就可以往下多发一组(4001~5000),2001到了再继续往下发一组(5001~6000).
在发送1~1000,1001~2000,2001~3000,3001~4000这组数据的过程中,不进行等待。在一份等待时间内等待了多份ACK。
如果一次批量发送数据为N,统一等待一波。此时这里N称为“窗口大小”,窗口大小是指无需等待确认应答而可以继续发送数据的最大值。
收到第一个ACK后,滑动窗口向后移动,继续发送第五段的数据。
操作系统内核为了维护这个滑动窗口,需要开辟发送缓冲区来记录当前还有哪些数据没有应答;只要确认应答过的数据,才能从缓冲区删除。
窗口越大,则网络的吞吐率越高。
当前窗口大小越大,可以认为是传输速度越快。窗口大了,同一份时间内等待的ACK就更多了,总的等待ACK的时间就减少了。
当这个2001的ACK到达之后,就认为1001~2000这个数据已经收到了,然后就可以立即发送下一组数据了。
随着ACK接连到来,随着接连的发送新的数据,此时这个“窗口”(要等待ACK的数据)就在逐渐的向后“滑动”。
那么如果出现了丢包,该如何进行重传?
情况一:数据包已经抵达了,ACK丢了
这种情况下,部分ACK丢了没事,可以通过后续的ACK进行确认。ACK确认序号的特定含义就保证了,后一条ACK能涵盖前一条。
在发送4001之前,收到了2001的ACK,但未收到4001的ACK。2001的意思就是说:在2001之前的数据已经全部收到了。
情况二:数据包直接丢了
当某段报文段丢失之后,发送端会一直收到1001这样的ACK,就像在提醒发送端(我想要1001)一样。
如果发送端主机连续收到三次同样一个"1001"这样的应答,就会将对应的数据1001~2000重新发送
这时候接收端收到了1001之后,再次返回的ACK就是7001(因为2001~7000接收端之前已经接收到了,被放到了接收端操作系统内核的接收缓冲区)
触发重传,这里的重传只是需要把丢了的那一块数据给重传,其他已经到了的不必再重传,整体的重传效率蛮高。这种重传机制被称为”快重传“。也叫”高速重发机制“
延迟应答(效率机制)
相当于流量控制的延申。
如果接收数据的主机立即返回ACK应答,这时候返回的窗口可能会比较小。
假设接收端缓冲区为:1M,一次收到了500K的数据;如果立即应答,返回的窗口就是500K,但实际上可能处理端处理的速度超快~10ms之内就处理掉这500k数据了。在这种情况下,接收端远远没有达到自己处理数据的极限,也就是说,在这种情况下,即使窗口再大一些,接收端也能处理得过来。如果接收端在接收到这500k数据后,稍微等一会儿再进行应答,比如等待200ms再进行应答,此时返回的窗口大小就是1M.
窗口越大,网络吞吐量越大,传输效率就越高。而我们的目标就是在保证网络不拥塞的情况下尽量提高传输效率。
那么,所有的包都可以进行延迟吗???
当然是有限制的:
数量限制:每隔N个包就应答一次。
时间限制:超过最大延迟时间就应答一次。
捎带机制(效率机制)
是延迟应答的延申。
在很多情况下,客户端服务器在应用层也是”一发一收“的,也就是说,客户端给服务器说”hello“,那么服务器也会回复客户端一个”hello“。
这时,我们的ACK就可以搭一个便车,和服务器回应的”hello“一起回给客户端。
对捎带应答来说,ACK已经和数据合体了(成为一个包了)。若ACK丢了,就是数据丢了,此时进行重传。
粘包问题
不是针对TCP的,而是针对于所有面向字节流的机制(读/写文件)
在TCP接收缓冲区中,如果若干应用数据包混在一起了,就分不出来谁是谁了。
在粘包问题中,这个包指的是应用数据包。在TCP协议头中,没有如同UDP一样的”报文长度“字段,但有一个序号这样的字段。站在传输层的角度上,TCP是一个一个报文传输过来的,按照序号排好,放在缓冲区。站在应用层的角度,能看到的只是一串连续的字节数据。那么对应用程序来说,这么一串字节数据,完全分不清楚从哪个部分到哪个部分是一个完整的应用层数据包。
这就是所谓的粘包问题。
解决粘包问题
明确两个包的边界
对于定长的数据包,保证每次都按固定大小读取即可。
对于边长的包,可以在包头的位置,约定一个包总长度的字段。也可以在包和包之间使用明确的分隔符。
TCP异常
进程终止:进程终止会释放文件描述符,仍然可以发送FIN。和正常关闭没区别。
机器重启:和进程终止情况相同。
机器掉电/网线断开:接收端认为连接还在,一旦接收端有写入操作,就会发现连接已经不在了,就会进行reset。即使没有写入操作,TCP的内部也有一个定时器。会定期询问对方是否还在,如果对方不在,就会把连接释放掉。
相关文章
- 谈一谈系统架构的性能优化思路
- 90%冠亚军采用的时间序列建模策略
- 揭秘:电脑上被删除的文件其实还在,那它们都去哪儿了?
- GAN靠「伪造思维」登上Nature子刊:首次合成神经活动数据
- 消息中间件RocketM高可用容灾设计架构
- 重新审视边缘计算的需求
- 软件开发工作量评估:基于FPA功能点分析法的深入解读
- 360测试之美(笔记)ppt分享五:数据构造平台进化史
- 清华大学用超算模拟量子计算机:4200万核CPU、性能可达440亿亿次
- 元宇宙大火,谷歌CEO:沉浸式计算的未来不属于任何一家公司
- 如果量子计算发展超过区块链技术 那么如何保护数字货币安全呢?
- 虚实结合:无需人工标注的可泛化行人再辨识
- 新题速看!2021阿里、腾讯、字节都在问的SQL数据库笔试题及答案都给你整理好啦!
- 函数或条件子句的占位符
- 数据万象书塾直播第一期火热报名中 | 直播间好礼享不停
- dipd:来自推特的破坏性事件预测数据集
- 10亿人脸数据全部删除!Facebook关闭人脸识别工具
- [网络安全] 十.Wireshark抓包原理、ARP劫持、MAC泛洪及数据流追踪-2
- 台积电交卷:已向美国商务部提供芯片供应信息,但未披露特定数据
- 计算走向商业化的趋势加强,数据存储成为必争之地