一篇文章帮你拿下面试八股文之网络三次握手四次挥手, HTTP超文本传输协议重点理论刨析到实现简单的HTTP服务, 思考着图解着学习网络 (咱不死记硬背)(1)

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

目录

一. 前言

二. 三次握手  (TCP连接建立)

面试灵魂拷问, 为什么是三次握手,而不是二次握手也不是四次握手?

三. 四次挥手 (TCP的连接断开)

面试灵魂拷问2,为什么是四次挥手, 而不是三次

四. HTTP超文本传输协议

啥叫作超文本, URL, DNS?

超文本传输协议HTTP(正式刨析)

然后简单的写一个HTTP服务器 (最简易版本)

五. 总结


一. 前言

  • 网络体系结构的宏观的认识, 方便后序的学习, 附上博客一篇:

https://blog.csdn.net/weixin_53695360/article/details/122989709?spm=1001.2014.3001.5502

https://blog.csdn.net/weixin_53695360/article/details/122754482?spm=1001.2014.3001.5502

  • C/C++  TCP网络编程实战篇基础: 附上链接两篇:

https://blog.csdn.net/weixin_53695360/article/details/122790450?spm=1001.2014.3001.5502

上述博客主要针对网络基础比较薄弱的博友们,  有了上述基础后序的知识可以更好的理解和吸收, 后序网络会陆续的刨析所有的网络协议, 希望友友们可以关注互访, 蟹蟹

二. 三次握手  (TCP连接建立)

  • 服务器端在一开始就调用listen() 函数进入监听状态, 阻塞监听着来自客户端的连接请求
  • 客户端调用  connect()  函数发起一个连接请求, 进入 SYN_SENT 状态
  • 服务端接收到这个连接请求, 将其放到SYN队列中, 应答客户端并且向客户端发起连接请求, 服务器进入SYN_RECVD状态
  • 客户端接收到服务端发送过来的数据包, 客户端确定连接建立, connect返回, 应答服务器且进入ESTABLISHED状态
  • 服务器接收到应答包, accept返回, 服务端确立连接建立, accept返回其实是从accept队列中拿取一个节点的.
  • 注意, 细节问题, 在上述过程中其实还存在两个队列, 一个叫做  SYN队列,也叫做等待队列, 是服务端接收到来自客户端的SYN请求之后都会将这个请求挂在SYN 队列下面,  还有一个队列叫做accept队列, 这个队列中都是完成了三次握手的请求, 也就是刚刚SYN队列中的对应节点直接转移过来的.   accept其实就是从 accept队列中拿取的一个节点分析返回connfd的

细节疑惑刨析

  • SYN  ACK  都是标志位   SYN: 标志发起一个连接请求   ACK : 标识确认号是否有效, 确认刚刚发起的连接请求是否收到, 标识应答.
  • seqnum  arcnum 都是序号,     seqnum是初始化序号,  是arcnum是确认序号(应答序号)

上述此处仅暂做简单理解, 后序分析各种协议报文的时候会详解.

面试灵魂拷问, 为什么是三次握手,而不是二次握手也不是四次握手?

  • 很多面经上面的的统一回答方向:  为了确立客户端和服务端双放的收发数据是否正常
  • 上述回答肯定是没有问题的,  毕竟三次握手就是为了在最小的资源浪费条件下让CS双方建立一个稳定的通信的连接通道
  • 第一二次握手, 客户端确定服务端是可以正常收到我的数据包的, 也是可以正常发送数据包的, 但是服务端并不知晓客户端是否可以正常接收到它的应答请求包, 它仅仅知道客户端发送是OK的
  • 第一三次握手,  服务端确定客户端是可以正常收发数据的
  • 四次五次乃至更多次握手不是不可以达到要求, 而是三次握手就足以建立CS双方稳定的连接, 所以没有必要再进行更多的资源浪费…

上述回答结束OK吗? 当然是OK的, 但是其实存在诸多细节没有刨析

从连接已失效的历史请求报文段的方向来思考为什么必须要三次握手而不是两次握手.

  • 上述就是两次连接会造成的经典问题, 连接历史包, 在拥塞的网络环境下, 可能刚开始一个客户端发送的历史包被网络阻塞住了, 新的客户端发送的连接还没有到来之前的历史失效报文段阻塞消失了, 并且 历史包还体现到达了服务端 , 两次握手, 服务端此时向客户端发出应答报文段完成连接建立, 误以为新的连接已经成功建立了, 就会傻等着这个客户端发送数据过来, 但是当然正在连接请求的客户端根本不认识这个server的确认连接的数据包, 不会理睬这个server的确认连接的信息,  重点来了, 这个时候没有第三次连接呀, 客户端倒是知道了这个数据包不对, 但是服务端 已经是确立连接的状态了, 就会一直等着服务这个客户端, 但是事实是人家不鸟他, 但是三次握手才让服务端确立连接就可以避免服务端的空白连接, 浪费服务端的资源

三. 四次挥手 (TCP的连接断开)

  • 第一次挥手, 客户端发送一个 FIN(结束), 用来关闭自己到服务器的连接, 注意: 是断开的客户端到服务器的单向连接, 仅仅只是客户端不可以再向服务端发送数据了**…  客户端进入FIN_wait1 状态**
  • 第二次挥手, 服务端接收到这这个 FIN , 先回一个 ACK, 我知道了,至此半关闭状态完成, 服务端进入 CLOSE_WAIT状态, 这个 CLOSE_WAIT的原因是因为, 服务端还需要将手头上没有发送完的数据包发送完, 因为一旦发送了 FIN(结束)就无法在发送数据了。。。   同时客户端收到ACK应答进入FIN_WAIT2状态
  • 第三次挥手,  服务端发送一个FIN(结束)到客户端, 关闭服务端到客户端的连接, 服务端至此进入LAST_ACK状态, 等待客户端确认
  • 第四次挥手, 客户端发送ACK 报文确定, 同时在等待  2MSL 之后完成CLOSE.
  • 2MSL  :   等待网络中残存的数据包丢失, 不然下一次复用同一个端口的时候可能会收到这些遗留的数据包, 造成错误
  • MSL :  (max segment live) 报文最大生存时间
  • FIN : 结束标志位        SYN : 同步连接标志位      ACK: 确认标志位    (常见标志位)

面试灵魂拷问2,为什么是四次挥手, 而不是三次

我们类比着三次握手来解释,  三次握手之所以是三次。 是因为第二次的时候是 SYN (同步序号)和ACK(确认应答) 合在了一起, 放在一个报文中发送给了客户端  (此处不懂请回溯)

But  :  四次挥手的时候   FIN 和 ACK  不可以放在同一个报文发送给客户端, 这个是为什么?

因为对方(Client)发送FIN 过来 仅仅代表客户端没有数据需要再发送给你服务端了, 但是你服务端可能还有数据需要发送响应给客户端, 所以你服务端暂时不能直接回FIN, 因为一旦回了FIN 就不可以再发送数据了, 所以只能先ACK, 等服务端把当前还需要发送的数据发送完再发送FIN 请求关闭连接.  ------   故此 FIN 和 ACK 需要分开

四. HTTP超文本传输协议

啥叫作超文本, URL, DNS?

  • 我听过超链接, 也听过文本, 但是木有听过超文本, 其实就是含有超链接的文本文件彼此之间链接起来, 形成网状,是不是迷糊了, 其实还有个别称: 网页.这些链接使用的都是URL, 不清楚这个的在写博文的时候点一下你的链接, 上面就有…
  • 啥是URL?   网页资源在服务器上的什么位置问题的解决,    网页是放在在服务器上的
  • DNS:域名系统     (解决IP地址不好记忆的问题), 记IP你能记住几个?? 根部记不住,

原理:

一个组织的系统管理机构, 系统内的每个主机的IP和主机名的对应关系.

如果新计算机接入网络, 将这个信息注册到数据库中;

用户输入域名的时候, 会自动查询DNS服务器, 由DNS服务器检索数据库, 得到对应的IP地址.

DNS系统: 是一整套从域名映射到IP的系统

超文本传输协议HTTP(正式刨析)

  • 超文本传输协议  :    通过URL的指示, 将服务器上的超文本文档(网页) 传输到 客户端(浏览器)上的一种应用层协议…
  • HTTP协议是基于TCP/IP的一个应用层协议
  • HTTP的工作原理图解如下

  • 上述图解分析的仅仅只是最为简单的最初版本的HTTP请求, 一次请求之后一个流程走完, 请求网页, 响应网页之后立马断开…   这个叫做  非持久性连接,
  • 问题  :   每一次请求网页都必须建立和断开一次TCP连接, 效率着实低下
  • 然后 HTTP  1.2 版本叫做持久性连接  :    正如其名:  它支持了一个连接中, 可以多次进行网页的请求和响应, 咱商量好哈, 咱不那么费, 访问的人多, 咱把这个连接的时间定的短一点, 不造成网络拥堵, 访问的人少, 咱把连接的时间定的长一点, 这个连接保持的时间可以应需求而定
  • 无状态性 :  就是说每一次访问都是新的一次访问, 服务器不知道你曾经是否访问过, HTTP的无状态性简化了服务器的设计, 使其更容易支持大量并发的HTTP请求**( 说实话这句话是网上抄的, 自己不是特别理解, 很朦胧, 要是大佬看见希望评论区留下您的理解, 大家有自己的见解都可以讨论, 万分感谢)**
  • 最后下面附上报文的各种请求方法截图一张:  (主要也就是  GET  和  POST一个是从服务器申请网页, 另外个是往服务器上 POST 网页

img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

  • 21
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值