
bit::Shadow✧(≖ ◡ ≖✿目录超时重传理解丢包问题动态超时情景应用层再理解connect() accept()read() recv()三次握手为什么要进行三次握手三次握手真的是三次吗四次挥手难以压缩为三次的原因四次挥手C端既然已经收到第一个ACK了close后为何能读取FIN的信息验证实验TIME_WAIT状态MSL时间段解决无法立即重启的问题滑动窗口滑动窗口的分界32位序号与32位确认序号的响应机制解决序号应答问题步骤快重传与超时重传快重传超时重传超时无应答分析三次握手中哪个阶段可以携带数据流量控制扩大因子 M受16位窗口指针字段限制而导致TCP最大65535字节吗拥塞控制——拥塞窗口算法拥塞窗口慢启动算法延迟应答捎带应答TCP小结TCP与UDP的选择问题超时重传理解丢包问题丢包分作两种情况1.未递达丢包。2.递达后应答丢包。丢包的确认未收到应答等待超时。等待时间受网络、环境变化而动态决定动态超时情景LinuxUnix 和 Win也是超时以500ms为一个单位进行控制每次判断超时重发时间都是500ms的整数倍。如果重发一次仍然得不到应答等待2*500ms后再进行重发。4*500ms---8*500ms指数级增长。累计一定重传次数认为网络/对端主机出现异常强制关闭链接。应用层再理解connect() accept()A段发送执行connect()发送链接请求状态码设置为STN_SEND。对端收到后状态码设置为SYN_RCVD并应答。A端收到后connect正式返回状态码设置为ESTABLISHED表明已经建立链接与对端确认链接间存在不可避免的时间差。对端接收到A端链接建立的应答后同样设置ESTABLISHED状态码accept()返回。可知connect()发起了三次握手之后OS自动进行三次握手而accept()没有参与三次握手read() recv()read write的对象是缓冲区UDP是直接构造数据报发送到网络而非网络相关的。具体什么时候传输由OS决策。这充分体现出用户应用层与系统间的忙闲不均形成的高效解耦架构。三次握手为什么要进行三次握手1.以最小成本确定全双工属性正常。网络正常2.已最小成本确认双方100%愿意。三次握手真的是三次吗即C、S端的第二次握手SYNACK可能以拆解格式先SYN后ACK等应答。注就像四次挥手也可以被压缩为三次挥手一样。但四次挥手难以压缩四次挥手难以压缩为三次的原因关键是发送端发送缓冲区极大概率仍然存在数据没有被发送完成。这背后是序号对数据完整性的掌控四次挥手C端既然已经收到第一个ACK了close后为何能读取FIN的信息man 2 shutdown 接口 {单向地关闭fd的读/写端链接 } 在FIN信号中被使用。总而言之close()后系统层均做了对应的保护机制极大限度地避免了数据丢失。验证实验.mp4版客户端 . . .服务端启动后主动断开 . . .显示TIME_WAIT状态TIME_WAIT状态最先请求结束连接的一方接受到ACK后即进入TIME_WAIT状态。MSL时间段当一端进入TIME_WAIT状态后吗最多需等待2*MSL的时间才会正常关闭释放资源。MSLTCP报文在网络内存活存的最大时间。通常是30s因此TIME_WAIT存在2*MSL的延迟就实现了无论是发送过来待接受的数据/发送的数据都可以保证接受/发送。这也是服务端bind error的原因:服务端绑定一个端口号待服务端终止结束程序必须再等待2*MSL的时间解决无法立即重启的问题man setsockopt待完善理解int opt 1; setsockfdopt(listenfd, SOL_SOCKET, SO_REUSEADDR, opt, sizeof(opt));导致的问题导致数据丢失的概率增加。但因为有序号的作用下大大减少了可能性。滑动窗口位置发送端的发送缓冲区和接收端的接收缓冲区都存在。以下仅探讨发送缓冲区滑动窗口的分界左侧已发送、已应答数据区。内部待一次性发送数据群。受网络、硬件条件反馈而动态变化窗口大小右侧待发送区域。32位序号与32位确认序号的响应机制确认序号反馈的代表接受小于序号标记的数据已送达。S端发送2001代表报文序号小于2001的数据S端均已接受到。解决序号应答问题步骤1.确认丢包是在C---S丢弃还是C---S丢弃。2.C---S应答的是S端已送达的数据序号。快重传与超时重传快重传快重传发送端收到了3次相同的财重复的应答———快重传立即补发超时重传超时无应答分析三次握手中哪个阶段可以携带数据答前两次不能携带数据第三次可以携带。建立连接未完全建立时双方缓冲区状态未知。禁止发送数据。但地三次握手时就可以携带数据了。流量控制响应场景适时控制发送数据流大小避免溢出、丢失问题。1.窗口探测发送数据端常常执行一不携带数据的报文报头向接收端探测其接受缓冲区剩余大小。2.窗口更新通知接受端发送对自己窗口大小剩余的描述。可能丢包发送端常时不时发送探测窗口包扩大因子 M受16位窗口指针字段限制而导致TCP最大65535字节吗答实际上TCP首部40字节选项中还包含了窗口扩大因子M实际窗口的大小为窗口值左移M位。实际窗口大小 TCP头中的窗口值 M拥塞控制——拥塞窗口算法拥塞窗口一种使用慢启动算法与接收方窗口共同限制滑动窗口大小的算法窗口。在该值以内网络大概率不拥塞值以上网络可能拥塞。滑动窗口的大小 min (对方窗口大小拥塞窗口大小)[滑动窗口大小] min(cwnd, rwnd);慢启动算法第一阶段指数级增长。第二阶段线性探测增长。第三阶段网络/硬件限制或者网络拥塞重新循环。当TCP开始启动的时候, 慢启动阈值等于窗口最大值;• 在每次超时重发的时候, 慢启动阈值会变成原来的一半, 同时拥塞窗口置回1;• 少量的丢包, 我们仅仅是触发超时重传; 大量的丢包, 我们就认为网络拥塞;当TCP通信开始后, 网络吞吐量会逐渐上升; 随着网络发生拥堵, 吞吐量会立刻下降;拥塞控制, 归根结底是TCP协议想尽可能快的把数据传输给对方, 但是又要避免给网络造成太大压力的折中方案.延迟应答如果接收数据的主机立刻返回ACK应答这时候返回的窗口可能比较小。假设接收端缓冲区为1M。一次收到了500K的数据如果立刻应答返回的窗口就是500K但实际上可能处理端处理的速度很快10ms内就把500K数据从缓冲区消费掉了这种情况下接收端处理掉还远没有达到自己的极限即使窗口再放大一些依然处理得过来。如果接收端稍微等一会儿再应答比如等200ms再应答那么这个时候的窗口大小就是1M一定记得窗口越大网络吞吐量越大传输效率就比较高。我们的目标是在保证网络吧拥堵的情况下尽量提高传输效率那么所有的包都可以延迟应答吗肯定也不是数量限制每隔N个包就应答一次时间限制超过最大延迟时间就应答一次具体的数量和超时时间依操作系统不同也有差异一般N取2超时时间取200ms。捎带应答在延迟应答的基础上我们发现很多情况下客户端服务器在应用层也是“一发一收”的。意味着客户端对服务器说了“How are you”服务器也会给客户端回一个“Fine”那么这个时候ACK就可以搭顺风车和服务器回应的“Fine”一起回给客户端TCP小结为什么TCP这么复杂? 因为要保证可靠性, 同时又尽可能的提高性能.可靠性:• 校验和• 序列号(按序到达)• 确认应答• 超时重发• 连接管理• 流量控制• 拥塞控制提高性能:• 滑动窗口• 快速重传• 延迟应答• 捎带应答其他:• 定时器(超时重传定时器, 保活定时器, TIME_WAIT定时器等)TCP与UDP的选择问题1.对于丢包问题容忍度较高对信息完整性要求高。使用UDP像聊天信息2.对于丢包问题容忍度极低就必须使用TCP。像登录、注册感谢支持长期连载欢迎关注