延迟应答、捎带应答、面向字节流的粘包问题、保活机制
延迟应答
是为了提高效率,在流量控制的基础上,尽量返回一个合理但是又比较大的窗口
延时应答其实就是让ACK的发送时间晚一会(不影响可靠性的前提下)延时的时间中就会给应用程序提供更多的消费数据的机会,此时时间到了,再发ACK的时候,得到的窗口大小(接受缓冲区的剩余空间就会更大)
所有的包都可以延迟应答吗?
不是,
数量限制,每隔N个包就会应答一次
时间限制,超过最大延迟时间就应答一次
具体的数量和超时时间, 依操作系统不同也有差异; 一般N取2, 超时时间取200ms(这个延时应答的等待时间不能超过超时重传的时间.
)
捎带应答
在延迟应答的基础上,为进一步提高效率引入的机制
面向字节流的粘包问题
标题是面向字节流的粘包问题 所以只要涉及到字节流都会有可能发生这个问题
首先要明确, 粘包问题中的 “包” , 是指的应用层的数据包.
在TCP的协议头中, 没有如同UDP一样的 “报文长度” 这样的字段, 但是有一个序号这样的字段.
站在传输层的角度, TCP是一个一个报文过来的. 按照序号排好序放在缓冲区中.
站在应用层的角度, 看到的只是一串连续的字节数据.
那么应用程序看到了这么一连串的字节数据, 就不知道从哪个部分开始到哪个部分 是一个完整的应用层数据包
所以粘包,粘的是应用层的数据报 就是导致处理数据的时候 容易读取半个应用层数据报的情况
那么如何避免粘包问题呢?
明确两个包之间的边界
对于定长的包, 保证每次都按固定大小读取即可;
对于变长的包, 可以在包头的位置, 约定一个包总长度的字段, 从而就知道了包的结束位置;
对于变长的包, 还可以在包和包之间使用明确的分隔符(应用层协议, 是程序猿自己来定的, 只要保证分隔符不和正文冲突即可)
对于UDP协议来说, 是否也存在 “粘包问题” 呢?
UDP协议是没这个问题的
TCP协议本身不帮你区分应用层数据报. (以字节为单位传输)
UDP协议没这个问题. (以UDP包为单位)
因为站在应用层的角度, 使用UDP的时候, 要么收到完整的UDP报文, 要么不收. 不会出现”半个”的情况
保活机制
在一些”异常情况”下,TCP对于连接会有特殊的处理。
进程奔溃
这种情况下 TCP连接会正常进行四次挥手端来连接(主要是进程退出 都会自动关闭相关的文件)
主机关机(按流程)
这个按流程就是用户一步一步合理关机
在关机的时候会强制杀死进程 杀进程的时候会进行四次挥手断开连接
主机断电/断网
接收方断电
当接收方断电 发送方发送消息的时候就会出现没有ACK的情况 =>超时重传 => 重传一定的次数 => 重置连接 => 放弃对方然后断开连接
发送方断电
对于接收方来说本来也不知道发送方啥时候发送消息那接收方会一直等下去吗?
肯定不会 其实在TCP中 互相会时不时给对方发送心跳包(一个毫无意义的数据报 只是证明对方还在线 还活着) 所以一旦一段时间都没有收到对方的心跳包 就可以认为对方已经挂了 就会断开连接
心跳包
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/152947.html