TCP延迟应答、捎带应答、粘包问题、异常处理
一、延迟应答
上篇博客我们讲到TCP滑动窗口、流量控制、拥塞控制。
如果接收数据的主机立刻返回ACK应答,这时候返回的窗口可能比较小。
窗口越大,网络吞吐量就越大,传输效率就越高。我们的目标是在保证网络不拥塞的情况下尽量提高传输效率~~
那么所有的包都可以延迟应答么?肯定也不是:(具体的数量和超时时间,依操作系统不同也有差异)
- 数量限制:每隔N个包就应答一次
- 时间限制:超过最大延迟时间就应答一次
二、捎带应答
在延迟应答的基础上我们发现,很多情况下客户端服务器在应用层也是 “一发一收” 的。意味着客户端给服务器说了"How are you",服务器也会给客户端回一个"Fine, thank you",那么这个时候ACK就可以搭顺风车,和服务器回应的"Fine,thank you"一起回给客户端~~
所以在一些场景下,四次挥手断开连接可能变为"三次"~~
三、面向字节流 – 粘包问题
四、TCP中的异常处理
- 程序崩溃了
进程异常退出~ 操作系统会回收进程的资源,包括释放文件描述符表。这样的释放操作就相当于调用了对应socket的close,执行close就会触发FIN报文,进一步开始四次挥手。
这种情况和普通的四次挥手其实没啥区别~~ - 正常关机 (通过开始菜单这种方式来关闭主机)
关机的时候系统会先强制结束所有的用户进程,和上述的那个进程崩溃类似。系统内核会进行文件描述符的释放操作,进一步进行四次挥手~~ - 主机掉电
可能伤硬盘~
1)掉电的是接收方。发送方不知道对面挂了,继续发数据,此时发的数据没有ACK了。发送方触发超时重传,重传几次之后仍然无应答,尝试重置连接 (复位报文段),也会失败。只能放弃连接了~~
2)掉电的是发送方。此时接收方就等着,但接收方也不是干等,等了一阵之后,就会发送一个"心跳包" !心跳包是周期性触发的:只是一个简单的不携带任何业务数据的包,存在的意义就是确认一下对方是否还在。如果对方不返回心跳包,就说明心跳遗失,说明对方挂了,此时也就会放弃连接了~~ - 网线断开
情况同主机掉电,只不过通信双方的主机都是好着呢,这两端各自按照上述讲的两种情况分别进行~~