TCP协议(“传输控制协议(Transmission Control Protocol”). )是当今使用最广泛的协议之一,首先我们要明确TCP协议是一个(1)有连接(2)可靠传输(3)面向字节流的一个协议。现在就来细数以下他具有的几大特点。
1. 确认应答机制
这是TCP协议可靠性的核心机制,接收方在收到发送方发出的数据时返回一个ACK,表示我已经收到数据了,然后,发送方在接受到接收方发送的ACK之后,再继续发送数据。对于发送的数据,TCP将每个字节的数据都进行了编号. 即为序列号. 假设每次发送1000个字节,发送方的序列号就是1,接收方收到数据后,给发送方返回1001,表示我已经收到数据,下次发送从1001开始。
2. 超时重传
这也是TCP协议可靠性的核心机制,与应答机制相辅相成
主机A发送数据给B之后, 可能因为网络拥堵等原因, 数据无法到达主机B; 如果主机A在一个特定时间间隔内没有收到B发来的确认应答, 就会进行重发。重传是为了进一步降低丢包的可能性,而这个“特定时间”,也会随着重发次数变得慢慢变得越来越长,若达到一定次数对方还没没响应,那么就会强制断开连接。
这里有一个需要注意的点,上面说B未收到A的数据可能是因为网络拥堵,那么假如B收到数据,返回的ACK同样也可能因为网络拥堵,导致A无法收到,此时A会因此重发数据给B,最终导致B接受了一堆重复数据,那么如何解决这些重复数据呢?
此时就用到了第一条里所说的序列号了,只要A发送的一样的数据那么序列号一定相同,B就可根据序列号来自动去重。
3. 连接管理
首先讨论一下建立连接的意义:
(1)可以试探一下对方是否适合和我进行通信
(2)可以协商一些重要数据,
接下来就是著名的TCP协议的三次握手。
1)客户端发送建立连接请求,SYN
2)服务端收到请求后,返回ACK,同时发送确认连接请求,SYN
3)客户端收到请求后,返回ACK

至此TCP连接建立,三次挥手完成
接下来是断开连接的四次挥手的过程
1)客户端请求断开连接,发送FIN
2)服务端接受请求并返回ACK
3)服务端发送断开连接请求,发送FIN
4)客户端收到后返回ACK

至此TCP连接断开
4. 滑动窗口
刚才我们讨论了确认应答策略, 对每一个发送的数据段, 都要给一个ACK确认应答. 收到ACK后再发送下一个数据段. 这 样做有一个比较大的缺点, 就是性能较差. 尤其是数据往返的时间较长的时候
既然这样一发一收的方式性能较低, 那么我们一次发送多条数据, 就可以大大的提高性能(其实是将多个段的等待时间 重叠在一起了).
这里我们假设发送3个数据,如果是直接仅仅是确认应答,那么发送第一个数据后只有收到返回的ACK才能发送下一个,而加入滑动窗口后就不太一样了,比如下图:在发送第一个数据后我可以不必等待ACK,而直接发送下一个,一次能发的最多数据数取决于滑动窗口的大小,以下图为例,我一次发送三个数据,此时窗口里的数据就是(1~1000,1001-2000,2001-3000),当我收到第一个数据返回的ACK时,此时窗口变成了(1001-2000,2001-3000,3001-4000).,相当于向下滑动了一格,由于3个时依次一起发送,可能会出现有的返回了ACK,有的没有。此处假设三个数据只有1-1000的ACK没有收到,那么发送端会重发此数据(1-1000),(及没收到谁的ACK就重发谁,不会三个一起发),等到都收到之后,接收端会从返回的ACK里的最大的开始继续发送,如下图,接收端就会从3001开始在发送一个窗口大小的数据(及3个)

简单来说就是:

5. 流量控制
接收端处理数据的速度是有限的. 如果发送端发的太快, 导致接收端的缓冲区被打满, 这个时候如果发送端继续发送, 就 会造成丢包, 继而引起丢包重传等等一系列连锁反应. 因此TCP支持根据接收端的处理能力, 来决定发送端的发送速度. 这个机制就叫做流量控制(Flow Control);
- 接收端将自己可以接收的缓冲区大小放入 TCP 首部中的 “窗口大小” 字段, 通过ACK端通知发送端;
- 窗口大小字段越大, 说明网络的吞吐量越高;
- 接收端一旦发现自己的缓冲区快满了, 就会将窗口大小设置成一个更小的值通知给发送端;
- 发送端接受到这个窗口之后, 就会减慢自己的发送速度;
- 如果接收端缓冲区满了, 就会将窗口置为0;
- 这时发送方不再发送数据, 但是需要定期发送一个窗口探测数据 段, 使接收端把窗口大小告诉发送端.
6. 拥塞控制
虽然TCP有了滑动窗口, 能够高效可靠的发送大量的数据. 但是如果在刚开始阶段就发送大量的数据, 仍然 可能引发问题. 因为网络上有很多的计算机, 可能当前的网络状态就已经比较拥堵. 在不清楚当前网络状态下, 贸然发送大量的数据, 是 很有可能引起雪上加霜的. TCP引入 慢启动 机制, 先发少量的数据, 探探路, 摸清当前的网络拥堵状态, 再决定按照多大的速度传输数据;
- 此处引入一个概念程为拥塞窗口
- 发送开始的时候, 定义拥塞窗口大小为1;
- 每次收到一个ACK应答, 拥塞窗口加1;
- 每次发送数据包的时候, 将拥塞窗口和接收端主机反馈的窗口大小做比较, 取较小的值作为实际发送的窗 口;
像上面这样的拥塞窗口增长速度, 是指数级别的. “慢启动” 只是指初使时慢, 但是增长速度非常快.
为了不增长的那么快, 因此不能使拥塞窗口单纯的加倍. 此处引入一个叫做慢启动的阈值
当拥塞窗口超过这个阈值的时候, 不再按照指数方式增长, 而是按照线性方式增长
当TCP开始启动的时候, 慢启动阈值等于窗口最大值; 在每次超时重发的时候, 慢启动阈值会变成原来的一半, 同时拥塞窗口置回1.

7. 延时应答
他存在的目的就是为了在可靠性的基础上让滑动窗口的值尽量大一些,简单来说就是在收到数据时不立刻返会ACK,而是稍等一会才返回 ,在等的过程中程序就会多消耗一些缓存区的数据,这样在返回的ACK中反馈接受缓存区剩余空间的大小,这个值会更大一些,从而时反馈的窗口的大小就会更大一些。
一定要记得, 窗口越大, 网络吞吐量就越大, 传输效率就越高. 我们的目标是在保证网络不拥塞的情况下尽量提高传输效 率;
那么所有的包都可以延迟应答么?
肯定也不是;
数量限制: 每隔N个包就应答一次;
时间限制: 超过最大延迟时间就应答一次
8. 捎带应答
他建立在延迟应答的基础上,简单来说就是操作系统内核返回ACK的时机和程序反馈响应的实际合二为一,通过同一个数据报返回俩方面的信息。
9. 面向字节流
主要指由于缓冲区的存在, TCP程序的读和写不需要一一匹配, 不管你是怎么写的,我想一次读几个就读几个,
*粘包问题:*TCP协议传输数据都是一段一段的,一个一个的报文,在应用层的角度来看,它就是一连串的字节数据,并不知道从哪个部分开始到哪个部分, 是一个完整的应用层数据包。
那么如何解决呢?
简单来说就是明确俩个包之间的边界,俩种方式:
(1)指定分隔符
(2)指定包的长度.
10.感谢阅读
TCP协议通过确认应答机制、超时重传、连接管理(三次握手、四次挥手)、滑动窗口、流量控制、拥塞控制、延时应答、捎带应答和面向字节流等特点实现可靠传输。确认应答和超时重传确保数据送达,滑动窗口提高性能,流量控制和拥塞控制避免网络拥塞,连接管理和断开连接保证稳定通信。
1409

被折叠的 条评论
为什么被折叠?



