持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第33天,点击查看活动详情
大家好,我是bug郭,一名双非科班的在校大学生。对C/JAVA、数据结构、Spring系列框架、Linux及MySql、算法等领域感兴趣,喜欢将所学知识写成博客记录下来。 希望该文章对你有所帮助!如果有错误请大佬们指正!共同学习交流
作者简介:
- CSDN java领域新星创作者blog.csdn.net/bug..
- 掘金LV3用户 juejin.cn/user/bug..
- 阿里云社区专家博主,星级博主,developer.aliyun.com/bug..
- 华为云云享专家 bbs.huaweicloud.com/bug..
连接管理(面试重点)
我们知道TCP是有连接的,所以传输数据之前必须双方进行连接!
那么如何进行连接呢?
3次握手
3次握手就是客户端和服务器建立连接的交互过程 这里的握手只是一个比喻,一次握手就好比一次交互过程,这里进行了3次握手也就是客户端和服务器建立连接需要进行3次交互才能实现!
3次握手就类似于打电话刚接通的过程:
经过这3次交互过程我们就可以知道双方的通话环境是否ok!
第二次握手,可以知道客户端的发送能力和服务器的接收能力没有问题!当进行最后一次交互握手过程时,就可以确认通信双方的可以进行通信!
上图就是客户端和服务器进行3次握手的过程!
TCP的状态:
LISTEN状态,表示服务器可以进行连接,等待连接状态,就好比手机开机,网络良好,等待电话!ESTABLISHED:表示通信双方已连接成功,就好比已经接通了电话,可以进行信息交流了!
3次握手有啥用?和可靠传输有什么关系?
- 3次握手相当于投石问路,检查一下通信双方的网络状态,是否满足可靠传输的基础,如果网络状态不好,就没有进行数据传输的必要了!经历了3次握手就可以验证双方的发送能力和接收能力,就好比打电话双方打通后需要验证双方的麦克风和喇叭!
- 让双方能够协商一些重要信息
为啥是3次握手,不能是4次?或者2次嘛?
上图就是4次握手,可以4次但是没有必要,我们可以将第二次
ACK和第3次SYN放在一个数据包中传输,没必要分开进行分封装分用,就好比你去一家店铺买2件衣服,商家肯定打包成一个包裹!
这里分开传输效率低!不如和在一起!
2次握手显然不行,因为进行次握手后,客户端知道了自己的发送能力和接收能力良好,但是服务器不清楚自己的发送能力和接收能力是否良好,进行3次握手双方才能确认了双方通信状态,进行接下来的数据传输!
3次握手就好比2个人谈恋爱是一歌双向奔赴的过程,所以其中的交互缺一不可,不然就不能确立男女朋友关系!
4次挥手
4次挥手客户端和服务器断开连接的过程!我们在进行3次连接后,在操作系统内核中保存了一些连接的信息,就是我们之前学过的五元组!断开连接的过程就是将保存的信息删除! 也就是相当于情侣之间分手的过程! 当俩个人确认关系后,那么双方会在心里留一块位置给对方,起码知道对象叫啥名,不然谈啥恋爱对吧,然后4次挥手就把心里的位置给腾开,把之前双方的信息给销毁!
CLOSE_WAIT:四次挥手进行了2次后的状态,这个状态就是等待代码中调用socketapi中的close方法进行接下来的挥手,如果一个服务器中出现了大量的该状态,大概率出现了bug!TIME_WAIT:谁发起的FIN谁就进入了该状态,表面上看A发送了ACK就没撒事了,但是有可能出现最后一个ACK丢包问题,所以TIME_WAIT状态会等待B的超时重传!要保证,B重传时,A还在连接! 一般A的等待时间是2*MSL,MSL是网络间,任意两点传输的最长时间!
我们此时又在想:3次挥手中间的ACK和SYN合在了一起,提高了传输效率,那么这里为啥不能是3次挥手呢?
3次握手中间两次可以合并,都是由操作系统内核完成! 而4次挥手有时候不能合并! 不能合并的原因B发送
ACK和FIN的时机不同,ACK是由操作系统内核发送,而FIN是代码中的socket.close方法才会触发,有时两者的时间间隔太大无法合并一起!