尽管TCP拥有滑动窗口这一高效的数据传输机制,能够确保在对方接收能力下将大量数据可靠发送,但在通信初期若盲目发送大量数据,仍有可能触发网络问题。
当网络出现问题时,通过滑动窗口等机制是没有办法解决的。网络拥塞就是一种情况,网络中需要处理的数据太多了,导致十分堵塞,此时就需要拥塞控制进行管理!那么如何识别出来时网络出现问题呢?当出现了大量报文的丢失问题时,就可以大概率确定网络出现了严重的拥塞问题!
考虑到网络中众多计算机的交互,当前网络状态可能已经处于相对拥堵的状况。在不明确当前网络状况的前提下,大量数据的急速发送很可能加剧网络拥堵,造成“雪上加霜”的效应。
为此,TCP采用了慢启动机制,它首先发送少量的数据包,以此作为“探针”来感知和评估当前网络的拥堵程度。在此基础上,TCP会根据网络的实际状况,逐步调整数据传输的速度,确保数据传输的平稳与高效。这样才能更高效的进行处理! 此处引入一个概念:拥塞窗口。
通过拥塞窗口,可以保证传输的数据不会超出网络的承载能力,也能保证不会超出接收端的接收能力! 网络的状态是浮动的,拥塞窗口的大小也是浮动的!那么主机如何得知拥塞窗口的接近大小是多大呢?这个大小是通过尝试出来的,是一个经验数据!
发送开始的时候, 定义拥塞窗口大小为 1,接受到ACK时就通过指数规律进行增长,这就是慢启动窗口。指数在变量较大时会发生指数爆炸,所以就有慢启动的阈值!当拥塞窗口超过这个阈值的时候,会改为线性增长,避免造成拥塞!
网络中每个主机都使用这样的拥塞控制机制,遇到网络拥塞时,所有主机都调整窗口为1,然后同一个慢启动算法逐渐恢复,最终找到下一次拥塞的临界值,继续调整… 这样动态调节,保证网络传输的效率最大!
在发送方和接收方进行通信时,接收方的接收缓冲区收到了来自发送方的一批报文(滑动窗口机制),接收方收到第一个数据时,不会立刻进行ACK,会延迟一会再进行发送!这个延迟时间不会超过超时重传的时间。这个延迟一会,就能保证,向发送方的ACK可以是更大的接收窗口,通过滑动窗口算法,就能让下次并发发送的数据更多!
一定要记得,窗口越大,网络吞吐量就越大,传输效率就越高。 我们的目标是在保证网络不拥塞的情况下尽量提高传输效率!
那么所有的包都可以延迟应答么? 肯定也不是!
具体的数量和超时时间,依操作系统不同也有差异。一般 N 取 2, 超时时间取 200ms。
延迟应答的效果再单台主机的通信中可能不明显,因为延迟的一会不一定会等到更大的接收窗口。但是网络中并不是只有一台主机!主机的数量是很多的,那么再小的概率,在如此大的基数中也是不容小觑的大小!所以延迟应答的效果在网络中是很棒的!
捎带应答(Piggybacking)是TCP协议中一种优化网络传输效率的机制。在TCP通信过程中,数据的发送方和接收方需要通过确认应答(ACK)来确保数据的可靠传输。捎带应答技术允许在数据传输的过程中,将确认应答信息“捎带”在数据包中一起发送,而不是单独发送一个ACK包!
通过我们对TCP报头结构的学习,捎带应答的本质就是在通过6位标志位:
每次传输的报文中,可以同时将多个标记位设置为1,那么这份报文就具有了多重含义!这样的传输策略大大提供了通信效率!
注意,三次握手的最后一次是可以进行捎带数据的 !
创建一个 TCP 的 socket, 同时在内核中创建一个 发送缓冲区 和一个 接收缓冲区。
由于缓冲区的存在, TCP 程序的读和写不需要一一匹配, 例如:
所以说TCP协议是面向字节流的,对方发送的数据不一定是一个完整的报文。发送的数据是对方操作系统从缓冲区中刷新过来的,也就是说这些数据是不确定的,不一定完整!
这种面向字节流的通信过程必然会有粘包问题:多个报文粘连在一起,无法区分!那么如何避免粘包问题呢? 归根结底就是一句话, 明确两个包之间的边界!
所以为了保证面向字节流的通信过程可以正常读取报文,就需要一些特殊处理,保证我们可以找到边界!之前在使用TCP进行Socket套接字编程时,通过设计报文为:"len"\r\n"{json}"\r\n
我们通过\r\n
找到len
报文长度,然后来判断是否有完整报文!
UDP协议中,有一个16位UDP长度。操作系统可以知道报文多长,一次性就能将整个完整报文发送出去!而在TCP中是没有TCP长度的!TCP是面向字节流的,不需要对长度进行处理!TCP协议不需要解决粘包问题,粘包问题是应用层需要解决的!TCP协议是通过字节流保证了通信的可靠性!
TCP在通信过程中如果发生异常怎么办?
ctrl+c
关闭服务端或客户端,这种就是进程终止,和正常关闭时一样的!操作系统会自动进行四次挥手经过三篇文章的讲解,现在我们已经对TCP协议有了一个大概的了解! TCP的可靠性通过:
TCP中提高性能的机制也很多:
实际使用中如何选择TCP/UDP ? 我们说了 TCP 是可靠连接, 那么是不是 TCP 一定就优于 UDP 呢? TCP 和 UDP 之间的优点和缺点, 不能简单的,绝对的进行比较
归根结底,TCP 和 UDP 都是程序员的工具,什么时机用,具体怎么用,还是要根据具体的需求场景去判定!!!