TCP协议
-
源/目的端口号:表示数据从哪个进程来,到哪个进程去
-
序号:TCP将每个字节的数据都进行了编号称为序列号,接收端收到数据之后要发送确认序号给发送端。序号用于对字节流进行编址,例如序号是301,表示第一个字节的编号为301,携带的数据长度是100,下一个报文的编号就是401
-
确认序号:期望收到的下一个报文段的序号,B收到A发来的一个报文段,序号是301,携带的数据长度是300,那么B发送给A的确认序号就是601
-
4位头部长度:表示TCP头部有多少个4字节,所以TCP头部最大长度为15*4=60字节
-
6个标志位
URG:紧急指针是否有效
ACK:确认号是否有效
PSH:提示接收端应用程序立刻从缓冲区读走
RST:要求对方重新建立连接,携带RST的标识的报文称为复位报文段
SYN:请求建立连接,携带SYN标识的报文称为同步报文段
FIN:结束标识,告诉对端本端关闭。 -
16位窗口大小:无需等待确认应答而可以继续发送数据的最大值
-
16位校验和:发送端填充,CRC校验,接收端校验不通过,认为数据有问题。校验和包含TCP首部和TCP数据部分。
-
16位紧急指针:标识那部分数据是紧急数据
TCP保证可靠传输的手段
确认应答机制
- 每个ACK包都带有对应的确认序列号,告诉发送端哪些数据已经接受到了,下一次应该发送哪些数据
超时重传机制
- 发送端给接收端发送数据,由于网络原因未能到达接收端,发送端在一个确定的时间内没有收到接收端的确认应答信息发送端就会重新进行发送。
- 如果是发送端的数据接收到了,但是接收端的确认报文丢失,那么接收端就会有很多重复数据,那么TCP就可以根据序列号识别出重复的包,并把重复的丢弃掉。
超时时间如何确定?
TCP为了在任何环境下都有比较高性能的通信,会动态计算最大超时时间
- Linux中以
500ms
为单位进行控制,每次判定超时时间都是500ms
的整数倍 - 重发一次之后没有应答,在等待
2*500ms
之后再进行重传 - 还得不到应答,等待
4*500ms
进行重传,一次类推 - 累计到一定的重传次数,TCP就会强制关闭连接
滑动窗口
使用确认应答机制,对于每次发送的数据都需要对方给一个应答,这样能保证可靠传输,但是在数据往返较长的时候性能就大大下降
为了提高TCP的传输效率,可以一次性发送多条数据(将多个段的等待时间重叠在一起),这样就可以大大提高TCP的性能。
- 滑动窗口发送前四个段的时候,不需要等待ACK,直接发送
- 收到第一个ACK后,滑动窗口向后移动,继续发送第五个段的数据
- 操作系统维护滑动窗口需要开辟发送缓冲区,记录哪些数据没有应答,只有确认应答过得数据,才会从缓冲区删除
- 滑动窗口越大,网络吞吐量越高
网络中没有百分百可靠的协议,数据包丢了怎么办?
数据包抵达,ACK丢失
使用滑动窗口ACK丢了并不重要,因为还有后序的ACK进行确认。
发送端的数据包直接丢了
- 如果上图中101-200的数据包丢失,那么接收端B会一直发送101这样的ACK,提醒发送端A我要的是“101这个数据”
- 如果发送端A连续三次收到同样的一个应答,那么会将对应的数据进行重新发送
- 接收端B接收到数据之后,再次返回最后接收数据的应答(B在给A发送ACK的同时也在接收A发来的数据,存放在B的接收缓冲区)
流量控制
接收端处理数据的能力是有限的,发送端发送太快,接收端的接收缓冲区被写满,那么这时候发送端继续发送数据,就会导致丢包,继而引起丢包重传等一系列连锁反应
所以TCP支持很据接收端的处理能力来决定发送端的发送数据,这就是流量控制
- 接收端将自己的缓冲区大小写入TCP协议中窗口大小字段,通过ACK通知发送端
- 接收端发现缓冲区快满时,会将窗口大小设置成一个更小的值发送给发送端
- 如果接收缓冲区已满,会将窗口大小设置为0发送给发送端,这时不在发送数据,但是接收方会定时发送一个窗口探测数据段,把窗口大小告诉发送端
TCP首部字段有一个16位窗口大小,也就是说窗口大小最大就是65535,在TCP首部40字节选项中还有一个窗口扩大因子M,实际窗口大小就是窗口字段值左移M位。
拥塞控制
在TCP刚开始建立连接,不可能一次行就发送大量数据,如果当前网络状态比较拥堵,那么发送的大量数据有很大部分都不会到达目的地
TCP引入慢启动机制,先探测当前网络状况,再决定传输速度
- 在刚开始的时候, 双方都维护一个拥塞窗口,发送开始,定义拥塞窗口大小为1
- 每接收到一个ACK应答,拥塞窗口加1,
- 每次发送数据包,将拥塞窗口和接收端主机反馈的窗口大小作比较,取较小的值作为发送的窗口
慢启动
延迟应答
- 窗口越大,网络吞吐量越大,传输效率越高,所以我们的目的是在保证网络不拥塞的情况下尽量提高传输效率
- 如果接收缓冲区为1M,一次收到了600K数据,那么立即应答,返回的窗口大小就是400K
- 如过接收端处理速度快,即使窗口再大一些,接收端也可以处理过来,如果接收端等待一会再应答,那么这时候返回的窗口大小就是1M,从而提高传输效率
延迟应答的限制
- 数量限制:每隔N个包就应答一次
- 时间限制:超过最大延迟时间就应答一次
TCP异常情况
- 进程终止:释放文件描述符,可以发送FIN,与正常终止无区别
- 机器重启:重启之前进程终止,可以正常发送FIN
- 机器掉电:接收端认为连接还在,一旦接收端有写入操作,发现连接已经不在,就会进行reset请求再次连接,连接失败接收端释放连接。同时TCP也内置了一个保活定时器,会定时询问对方是否还在,如果不在也会释放连接
IP协议
- 4位版本号:指定IP协议的版本,对于IPv4来说就是4
- 4位头部长度:IP头部长度有多少个4字节,所以头部最大长度就是15*4=60字节
- 8位服务类型:3位优先权(已弃用),4位TOS字段,1位保留字段(必须设置为0)。4为TOS为:最小延时,最大吞吐量,最高可靠性,最小成本,这四个只能选择一个
- 16位总长度:IP数据报整体占多少字节
- 16为标识:唯一的标识主机发送的报文,IP报文在数据链路层被分片,那么每一个片中的标识都是相同的
- 3位标志字段:第一位保留,第二位置1表示进制分片(报文长度超过MTU,丢弃报文),第三位更多分片,最后一个分片是1,其他是0
- 13位分片偏移:相对于原始IP报文开始处的偏移
- 8位生存时间:数据报到达目的地的最大报文跳数,每经过一个路由,TTL-=1,一直到0都没有到达目的地,报文丢弃。
- 8位协议:表示上层协议类型,把IP交给TCP还是UDP,其中ICMP是1,TCP是6,UDP是17
- 16位头部校验和:使用CRC校验,鉴别头部是否损坏
- 32位源地址和32位目标地址:表示发送端和接收端
以太网帧
- 目的地址和源地址是指网卡的硬件地址,长度是48位
- 帧协议类型字段有三种值,对应IP,ARP,RARP
- 末尾是CRC校验