文章目录
TCP和UDP都是传输层的协议!
UDP
特点
1.无连接(不需要先建立连接,就可以直接进行通信)
2.不可靠(发送者不知道接收者是否接收到了数据)
3.面向数据报(以DataGramPacket为单位进行读写数据)
原理
UDP协议格式
UDP传输过程
假设QQ用的是UDP协议,以发qq消息为例
对校验和的理解
UDP没有拥塞控制:应用层能够更好的控制要发送的数据和发送的时间,网络中的拥塞控制也不会影响主机的发送效率。某些实时应用要求有稳定的传输速率,容忍小部分数据丢失,但不允许有较大的延时(例如:直播)
TCP
TCP报头结构
TCP的十个重要特性
1、确认应答(可靠传输的最核心机制)
举个例子:有一天晚上约柯基女神吃麻辣烫 发个短信~~
短信是不太可靠的,我如何知道对方是否接收到了我的消息?
通过确认应答这样的机制就构建出了最简单的可靠性,接收方反馈一个应答报文(ACK)表示收到了。
现在我发送过去两条消息,同时柯基也回复了两条,但是此时不能确定收到的两条回复各自对应的是哪条问题!在网络中也可能会出现“后发先至”的情况,很容易产生歧义!如果,柯基通过下面的方式进行回答,就不会产生歧义:
此时,在应答报文中就引入了其他的东西,保证即使顺序出错也能正确应答,不会出现歧义。
此时针对发送的请求进行编号,应答的时候也针对编号进行应答,这样既能正确应答请求,也不会浪费太多的空间和带宽。
对应到TCP的报文中就是32位序列号和32位确认号。
上面的情况还不太严谨,真实的TCP还不太一样。TCP是面向字节流的,此处的编号并不是按照一条两条来编的,而是按照字节来编号的,每一个字节都有一个编号。
2、超时重传
确认应答是比较理想的状态,在实际的传输过程中是可能会丢包的。
如果我发送消息给女神,女神过了好久都没回复,那么就有可能是我没成功发送消息。
丢包有两种情况:
- 发送方的请求(SYN)丢了
- 如果SYN丢了,重传是没有任何问题的
- 接收方的回复(ACK)丢了
- 如果是ACK丢了,那么接收方是已经成功接收到数据的,如果重传就意味着接收方收到了相同的数据。 TCP内部在这里进行了处理,TCP内部会以序号为key对数据进行去重操作,保证应用层读到的数据不是重复数据。
那么上图中的t1和t2是一样长的嘛?不是的,t2会比t1更长一些。
TCP抱着一种“悲观的态度”,当一次丢包重传之后,TCP就认为后面的重传大概率是没有什么用的,此时重传的时间间隔更长,节省带宽。
确认应答和超时重传是保证TCP可靠传输的两个核心机制。
3、连接管理
3.1 建立连接的过程(三次握手)
为什么要建立连接
1、更好的保证可靠性:建立连接的过程其实就是在让通信双方验证各自的发送能力和接收能力是否正常。
2、协商一些具体的参数
具体是如何建立连接
建立连接的过程就类似于打电话开始的部分。
TCP中真实建立连接的过程
两次是否可以完成建立连接?不能
继续用打电话的例子,如果没有最后一步,我给柯基女神反馈,柯基女神就无法知道我的听筒和自己的话筒是否工作正常。
如果建立连接是四次握手行不行?行,没必要
这样做也可以验证双方的接收和发送能力是否正常,但是这样做效率太低。传输一个包肯定比传输两个包的效率高。
真实的建立连接的过程:
建立连接之初,客户端和服务端都是处于CLOSED状态,客户端主动打破关闭状态向服务端发送建立连接请求,此时客户端处于SYN_SENT状态,等待服务端响应;此时服务端收到请求,被迫启动,并进入LISTEN状态,服务端通过客户端发来的SYN知道客户端请求建立连接,然后服务端给客户端返回ACK确认应答,以及向客户端请求建立连接,此时服务器进入SYN-RCVD状态;此时客户端收到服务端的请求和应答之后,确认ACK有效后进入ESTABLISHED状态,并发送ACK给服务端;服务端在验证ACK有效后也进入ESTABLISHED状态。
建立连接的过程也是会丢包的,如果丢包就会触发超时重传。
3.2 断开连接的过程(四次挥手)
假设我和柯基已经好上了,长久的爱情都能互相容忍对方的缺点,但是有一点我忍不了,柯基喜欢扣脚,于是
**三次握手:**双方各自向对方发起建立连接的请求,再各自给对方回应,只不过中间的SYN和ACK可以合并在一起。
**四次挥手:**双方各自向对方发起断开连接的请求,再各自给对方回应,只不过中间的FIN和ACK不一定可以合并在一起。
具体如何断开连接
建立连接的过程中ACK和SYN都是由系统内核决定的,所以可以合并在一起。
CLOSE_WAIT和TIME_WAIT
为什么在四次挥手过后要等2MSL时间才关闭连接
主机B在给主机A返回ACK和FIN时,ACK丢了,FIN没丢
断开连接可以是三次嘛?可以,但是要在特定情况下
4、滑动窗口
滑动窗口的本质就是批量传输数据,就是在保证可靠性的前提下尽可能的提高效率。
4.1 没有滑动窗口
在没有滑动窗口的机制下,传输N份数据就需要N次应答时间
总的传输时间:N份传输数据时间 + N次应答时间
4.2 有滑动窗口
在有滑动窗口的机制下,传输N份数据时间就重叠成了1份时间,应答N份数据时间也被重叠成了1份时间。
窗口:不等待ACK的情况下,批量发送的最大数据量,就叫“窗口大小”(上图的窗口大小就是4000)
滑动:形象的比喻”
窗口范围:表示当前那些数据在等待ACK,随着一个ACK到达就立刻发送下一个数据;等待数据包的范围就在逐渐滑动
4.3 丢包问题的处理
数据包抵达,ACK丢了
1001这个ACK丢了,2001没丢,发送方收到2001后就确定1-1000也成功到达,1001丢了无所谓,2001中能够包含1001ACK中的信息。就算是最后一个数据发完了,也还有FIN。
所以,如果是ACK丢了,但是数据包已经抵达,是不需要进行任何处理的。
数据包丢了
5、流量控制
窗口大小不能无限大,传输速率过快,接收方可能处理不过来。
根据接收方处理数据的能力来反向制约发送方的发送速率。(窗口大小)
通过接收缓冲区的剩余空间大小来决定发送方速率的。
窗口的大小是动态变化的
6、拥塞控制
流量控制和拥塞控制共同制约发送方的窗口大小。
拥塞控制由于不好衡量传输路径的拥堵情况,只能通过“反复试探”的方式,试探出应该用多大的窗口大小。
拥塞控制,这是一个动态变化的过程。
6.1为什么要动态变化?
网络的拥堵情况也是瞬息万变的,要随时根据网络的实际情况进行动态调整。
7、延时应答
目的是为了提高效率,在流量控制的基础上,尽量返回一个合理但是又比较大的窗口。
举一个例子
延时应答就是在不影响可靠性的前提下让ACK的发送时间晚一下。
延时的时间中就会给应用程序提供更多的消费数据的机会,此时时间到了再发ACK的时候,得到的窗口大小(接收缓冲区剩余空间的大小就会更大一些)就会更大一些。
延时应答的时间不能超过超时重传的时间。
8、捎带应答
在延时应答的基础上,为了提高效率进一步引入的机制。
9、粘包问题
严格说不是TCP自身的机制,而是面向字节流传输所具备的共性问题。
粘包“粘”的是应用层的包,导致处理数据时容易读取到半个应用层数据包。
面向字节流一次读一个字节,或者一次读两个字节,一次读n个字节都是可以的。
10、保活机制
TCP十大特性总结
保证可靠性的前提下,尽可能的减少效率的损失
TCP和UDP对比
1、TCP适用于要求可靠性的场景,外网通信,网络环境复杂,使用UDP容易丢包概率大。
2、UDP适用于对效率要求高的场景,对可靠性要求不高。
- 例如:机房内部通信。如果两个主机在同一个机房内部,两台主机之间的网络环境简单,丢包概率较小,就可以使用UDP。
3、UDP能实现广播,TCP只能一对一传输。
UDP如何实现可靠传输?
确认应答,超时重传。