TCP的三次握手四次挥手
三次握手:建立连接(保证连接建立的可靠性)
四次挥手:解除连接
三次握手连接四次挥手断开连接
理解ESTABLISHED:进入此状态下即可发送数据
理解TIME_WAIT状态:进入TIME_WAIT并不会马上将我们刚开始绑定的端口号释放而是在两个MSL之后在会将这个端口号释放掉,那么为什么是两个MSL(MSL是TCP报文的最大生存时间),因为要保证最后一个报文可靠到达
确认应答(ACK)机制:TCP对我们要发送的数据都进行了编号,在我们客户端和服务器传输数据的时候,有确认应答的机制,就是告诉发送方,你现在发送的这个消息已经发送成功了,并且告诉你下一个要发送的数据是从哪开始发
超时重传机制:当A给B发送消息的时候,如果超过一段时间没有收到B发来的ACK就直接进行重传
滑动窗口:当双方通信的时候我们若一直等待对方回应了ack之后在继续发送消息的话,其实效率是十分低的,呢么我们为了提升效率,就出现了滑动窗口,我们会在TCP报文里的2个字节保存滑动窗口的大小,举个栗子
-
滑动窗口的大小是指无需等待确认应答可连续发送数据的最大值,比如上图的滑动窗口的大小为4000(四个段)
-
在我们发送这四个段的时候无需等待确认应答ack
-
操作系统为了维护这个滑动窗口,会开辟发送缓冲区来记录当前还有那些数据没有应答,只有应答过的数据才会从缓冲区中删除
-
窗口越大,网络的吞吐率就越高
数据丢了,怎么重传?
-
ack丢了,这个没事,我们可以通过后面的ack来确认
-
数据丢了,当一段报文丢失了之后服务器端给客户端回复的ack中就会告诉客户端下一个是丢失的数据段,发送三次之后,就会启动重传机制(快重传)
流量控制
首先我们服务器处理数据的能力是有限的,当服务器收到大量的数据的时候,服务器的数据缓冲区被打满,服务器处理不过来,数据丢失,就会触发一系列的丢包重传问题,致使效率低下
所以TCP协议针对,出现了流量控制,就是在我们的服务器端的返回的报文中添加一个窗口大小的字段(2字节16位),即将滑动窗口的大小发送到客户端,而客户端接收到了这个报文之后,发现滑动窗口的大小变小之后就会立刻减缓数据的发送速度,以此达到流量控制,当滑动窗口的大小变成0 了之后,客户端就不去在发送数据,但是他会定时的发送一个探测数据来探测滑动窗口的大小,如果窗口大小变大,就会继续发送数据
拥塞控制
当我们刚开始启动客户端和服务器的时候,如果一瞬间就发送大量的数据也会发生问题,所以我们就引入了拥塞控制,执行慢启动机制,先发少量的数据来探测网络的状况,再决定按照多大的数据传输速率来传输数据,慢启动知识启动慢,但是增长速度非常快
延迟应答
当客户端发送数据给服务器的时候,如果我们立刻将ack返回此时我们返回的窗口大小可能较小,比如说我们滑动窗口的大小为1M,我们第一次发送500K的数据,如果此时对端直接返回ack的话那么此时返回的滑动窗口的大小为500K但是此时如果我们服务器端收到的500K的数据之后处理数据的速度非常快,那么其实我们的就可以等待数据处理完成的时候在返回ack此时我们的窗口大小为1M,我们一定要知道滑动窗口的大小越大,网络的吞吐率越高,数据传输越快
一般超时时间为200ms
粘包问题
包是应用层的数据包,因为首先TCP是面向数据流,它的数据是一个一个的字节序来排列,站在应用层看到的只是一个字节流,那么应用程序看到这个字节流就不是道这个数据是从哪开始从哪结束,解决粘包问题就是明确连个包之间的边界
对于定长的包,按长度进行读取即可
对于变长的包,在包的头部保存这个包的大小按大小读取
对于变长的包,在包的边界明确的写一个边界符来区分包的边界(应用层协议)
UDP不会存在粘包问题,因为他本省就是面向字节报的协议,它发送数就是一个报文一个报文发的,不存在发半个报文的情况
TCP异常
进程终止:依然可以发FIN跟正常结束没啥区别
机器重启和进程终止一样
机器断电和网络断开:保活计时器定期询文对方是否还在,,如果不在就直接断开连接
某些应用层协议也会有检测机制,比如说HTTP长连接,QQ断线了之后会定期的重新申请连接
TCP小结
可靠传输
-
确认应答
-
校验和
- 字节序
-
超时重发
-
拥塞控制
-
流量控制
提高性能
-
滑动窗口
-
快重传
- 慢启动
- 延迟应答
- 捎带应答
基于TCP协议的应用层协议
-
HTTP
-
HTTPS
-
SSH
-
SMTP
-
FTP
TCP/UDP协议的对比
TCP(可靠传输)用于发送精确的的数据信息,文件传输或者是重要的数据更新
UDP(高速传输)用于高速传输数据和实时性要求较高的通信领域,比如说QQ视频语音,实时数据的传输
用UDP实现可靠传输
在应用层定制一些协议,引入确认应答机制,超时重传机制,引入序列号