传输层
传输层负责端到端之间的传输
源ip/源端口
目的ip/目的端口
ip地址,是一个32位的整数,IP协议中来描述的(网络层)
端口号,区分一台主机上的哪个程序,是一个16位的整数(传输层)
端口号有效范围:0 ~ 65535
冗余:加强了可靠性,但是降低了数据一致性(异地多活)
例如:网线内部8根线
UDP
1丶 UDP长度上限是64kb
2丶UDP检验和(校验和)
3丶UDP校验和使用了一种很简单粗暴的CRC校验
4丶取每个字节,把每个字节的数据依次循环相加,得到一个最终的数字,就是校验和
5丶接收端按照同样的规则再次计算校验和,和发送端的校验和进行对比,如果数据一致,就可以认为数据没有发生错误
TCP设计核心
* 可靠性:发送者能知道自己发送成功没成功
* 传输效率:可靠性的前提下尽量提高传输效率
确认应答(ACK)
保证可靠性的核心机制
为了区分当前是应答哪个数据,需要引入序号和确认序号概念
序号是给每个字节都编了号确认序号表示的是当前序号之前的数据,已经收到了同时也意味着向发送端索要当前确认序号开始前的数据
超时重传机制
传输一条数据没有确认应答的时候,等待一段时间,然后进行重传,重传可能会重复若干次,重传的次数越多,丢包的概率也就越小,重传的等待时间间隔,也在变长
连接管理
三次握手建立连接
四次挥手断开连接
建立连接的意义:
*
双方各自试探对方是否适合建立连接,双方的书写数据的能力
*
双方可以在建立连接的过程中协商一些必要的数据,TCP的序号的基准值
三次握手具体过程:(SYN 和 ACK )(都是由内核)
* 客户端先发起一个建立连接的请求(SYN 同步报文段),服务器收到SYN后会立刻返回一个确认报文段ACK,同时回复的这个ACK也是一个SYN,客户端收到SYN也会返回一个ACK
涉及到的重要状态:
* LISTEN状态,服务器端的状态,表示随时可以建立连接
* ESTABLISHED状态,表示连接已经建立,随时可以通信
四次挥手断开连接:(FIN 和 ACK)
主动方可以是客户端也可以是服务器端
ACK 是一收到FIN,内核立刻回复
FIN 是程序中调用socket对象的close方法时才会发送
CLOSE_WAIT:
等待程序调用close来完成最终的断开连接过程
如果一个服务器上出现大量的CLOSE_WAIT是啥情况?
因为代码里有bug,代码里的close忘记调了,或者没有执行到
TIME_WAIT:
虽然此时程序可能已经结束了,但是还要保持连接为TIME_WAIT状态一段时间,因为发送的最后一个ACK可能会丢包(还没处理)
TIME_WAIT等待时间是2MSL(120秒)
MSL成为网络上两个主机之间数据传输的理论最大时间,在Centos7上默认是60秒
滑动窗口
* 窗口:不等待ACK的情况下批量发送多少数据
* 滑动:每次收到一个ACK之后,就依次发送下一条数据,等待ACK的数据区间就在往后移动
* 窗口越大,传输效率越高
* 可靠性,如果窗口无限大,那么接收端可能处理不来,网络环境也可能承载不了
如果在滑动窗口过程中丢包了怎么办?
1丶如果ACK丢了,不用管,确认序号表示的含义是当前序号之前的数据都收到了,后一个ACK能涵盖前一个ACK的含义
2丶如果是数据丢了,接收端就会反复尝试索要该丢掉的数据,重复如干次之后,发送端就会认为丢包了,并重传对应的数据,而对于已经发送成功的数据,则没必要再重传
流量控制:限制滑动窗口大小的一种机制(根据接收端的处理能力来进行限制)
接收缓冲区
接收缓冲区剩余空间越大,处理能力越强
接收缓冲区剩余空间越小,处理能力越弱
拥塞控制:
根据网络的拥堵情况,来限制发送端的发送速率
* 试探式的方式:刚开始先使用比较小的滑动窗口,如果没丢包,说明网络畅通,增大滑动窗口,如果丢包,说明网络拥堵,减小滑动窗口
发送端真实的滑动窗口大小 = min(流量控制中的窗口大小,拥塞窗口)
延时应答:
提高传输效率的方式(尽可能的提高窗口大小)
* 延时应答导致延时时间中,接收端的程序已经处理了一部分数据,此时ACK中的窗口大小就更大了
捎带应答:
延时应答的基础上,再提高传输效率
*
延时应答的基础上,把应用程序发送的业务数据和系统发送的数据合二为一
可靠性
* 确认应答
* 超时重传
* 连接管理
传输效率
* 滑动窗口(流量控制(延时应答(捎带应答)) 拥塞控制)
面向字节流
粘包问题(面向字节流导致的问题)