TCP协议报文的构成如下:
确认应答机制关键就在于:接收方在收到数据后,会向发送方回复一个类似于“收到”的消息(ACK)
但是如果发送方同时发送多个数据,就可能有如下情况(后发的消息可能先到达)
上述就会导致接收方收到的消息不能正确传达给发送方,所以需要引入一个序号
这就是TCP报头中的 序号 和 确认序号,TCP中的序号与确认序号是按照字节进行编号的 。
但是当传输过程中出现丢包时,不能正确返回ACK,发送方就不能发送接下来的数据,所以就会触发 超时重传
当数据在传输过程中丢包时,会触发超时重传 — 在一定时间内没收到ACK,发送方就重新传一次数据
但是如果是ACK丢了,发送方就会发送两次数据(但是TCP内部会自动去重),就不会导致接收方收到两次重复的消息
当网络遭受严重伤害,发送方重传多次都没有收到ACK,发送方就会放弃重传,自动断开 TCP 的连接
客户端与服务器如何建立连接 — 三次握手
客户端和服务器经过 三次交互,建立连接 ,在三次握手没问题的前提下,就可以确定当前网络满足可靠传输的基本条件
将接收方的ACK和SYN封装为一次发送,更高效
为什么非要三次握手?两次行不行?四次行不行?
两次不行!!!三次握手是在检测进行通信的双方,发送能力和接受能力是否都正常。
四次行,但没必要! 将中间的两次合并,效率更高!
经历了上述的三次交互过程,就能确定通信双方的 发送能力 和 接受能力都良好,具备可靠传输的前提,能建立连接。
当客户端与服务器建立连接后,就需要用一定的数据结构来保存连接的相关信息(源IP,源端口号,目的IP,目的端口号,协议类型)
客户端与服务器如何断开连接 — 四次挥手
客户端和服务器要断开连接,就需要释放掉保存的连接信息。
四次挥手 可以是客户端发起的,也可以是服务器发起 的。
四次挥手中,2,3发送的时机不一样,所以一般不能合并起来发送,如果两个发送的时间差很小,就可以合并。
必须四次挥手都完成后,双方才断开连接。
第三次挥手后,A将ACK发过去后,就立即断开连接吗?
不行!!如果A将ACK发过去后就断开连接,假设此ACK丢包了,就会触发B的超时重传,B重新发送的FIN就无人响应,所以A要等一段时间,这个等待的状态就叫做 TIME_WAIT。在确保B不会重传了之后,再真正断开连接。这个等待时间是(2 * MSL)
MSL:网络上任意两点之间,传输所需的最大时间。一般设为 60s
由于确认应答机制的存在,发送方在每次发送完数据后,都会等待接收方的ACK(导致大量的时间都花在等待ACK上面了)
为了保证传输效率,所以一次发送一波数据
上述例子中,一次发送四组数据,然后统一等待ACK,就将等待ACK的时间压缩了。
当发送方收到第一组ACK时,就继续发送下一组(4001~5000)的数据,此时等待的ACK的范围就发生了变化(2001,3001,4001,5001),后面的同理。
窗口越大,传输效率越高 窗口越大,一份时间里就可以等待更多的ACK,总的等待时间更少。
但是如果滑动窗口下丢包了,怎么处理呢?(快速重传)
1、假设ACK丢了
没有问题,直接继续发送,当收到 “下一个是2001” 的ACK时,说明2001之前的数据已经都收到了,所以有没有收到1001的ACK无所谓了,直接可以继续向下发送
2、假设数据丢了(触发重传)
当没有收到数据(假设为1001~2000),接收方就会一直向发送方索要1001 ~ 2000的数据
当发送方连续三次收到同样的ACK时,就会触发重传
同理,如果中途有其他数据丢包,接收方也会反复向发送方索要该数据,直到收到重传的数据。
UDP协议报文的构成如下:
可以看到,因为UDP报文长度为2个字节(64k),所以UDP数据报单次最多只能传输64k的数据,这也是UDP使用过程中一个致命缺陷。
当需要传输比较大的数据时,需要在应用层进行分包(将数
据拆成多个部分),分别发送。
校验和(校验接收方收到的数据是否出错)
UDP传输的特点