9.20 知识点查漏补缺

1.你的服务器解析 HTTP 报文的时候,怎么区分报头和正文?

读到连续\r\n\r\n,代表报头结束,后面根据 Content-Length 读取对应长度的正文。

2.Content-Length 作用?

标记请求正文的字节数,用来解决 TCP 粘包,确定读到哪里结束。

3.TCP报文是什么样的?

HTTP 请求报文由 4 部分组成:请求行、请求报头、空行、请求正文,空行用来分隔报头与正文。

①请求行(报文第一行) 格式:请求方法 + URI + HTTP 版本 + \r\n 作用:说明本次请求的操作类型、访问资源路径、使用的 HTTP 协议版本。 例:GET /index.html HTTP/1.1

②请求报头(多行键值对) 格式:Key: Value\r\n,可以有多行。 作用:传递请求附加信息。 常见:Host(目标地址端口)、Connection(keep-alive 长连接)、Content-Length(正文字节长度)、User-Agent(客户端标识)。

③空行 单独的\r\n,标志请求报头结束。必须有,用来分割报头和请求正文。

④请求正文(可选) 客户端提交的业务数据。

  • GET:一般不带正文;
  • POST/PUT:携带正文,例如表单、JSON。 服务器依靠Content-Length获取正文长度,用来处理 TCP 粘包,确定读取多少字节。

3.解析响应报文和请求报文最大的难点差别?

部分 Request(请求) Response(响应)
首行 请求方法、URI、HTTP 版本 HTTP 版本、状态码、状态描述
报头 客户端的附加信息 响应资源的附加信息
正文 客户端上传数据(可选) 服务器返回资源(可选)

解析请求要解析 URI、请求方法;解析响应首先解析状态码,报头和正文的解析逻辑是同一套。

4.C++ 读取文件三种方式对比表

对比维度 std::ifstream(C++ 流) fopen/fread/fclose(C 库) open/read/close(Linux 系统调用)
所属层级 C++ 标准库封装 C 标准库封装 操作系统原生 API
RAII 自动关闭 ✅ 是,对象析构自动 close ❌ 否,必须手动 fclose ❌ 否,必须手动 close
跨平台 ✅ Linux/Windows 均可 ✅ 跨平台 ❌ 仅 Linux/Unix
缓冲区 自带流缓冲区 自带 stdio 缓冲区 无缓冲,直接系统调用
类型安全 ✅ 类型安全 ❌ void*,需手动转换 ❌ int fd,错误码手动判断
性能 有一层封装,略低 略高于 ifstream 最高,几乎无封装
精细控制 一般 一般 ✅ 可设置 O_NONBLOCK 等
与 string 配合 ✅ 友好 需 char * 手动转换 需 char * 手动管理
适用场景 应用层业务代码、配置 / 网页读取 老 C 项目、简单读写 高性能 IO、非阻塞网络编程

5.std::smatch的作用

std::smatch 是 C++ 正则库的匹配结果对象,用来保存正则表达式捕获出来的子串。 一般和 regex_match 一起使用,_matches[0]是完整匹配内容,下标 1、2 对应各个括号分组捕获的内容。在我的 HTTP 服务器项目中,用来解析请求行,提取请求方法、URI、协议版本。

7.搜索二叉树和红黑树的区别?

8.URL和URI的区别

这个位置是URI,是URL的一部分,比如https://mp.csdn.net/mp_blog/creation/editor?spm=1001.2014.3001.4503 这个就是一个URL,而URI是edlitor?spm-1001,2014,3001这个

9.http响应的重定向字段的含义

重定向就是服务器返回 301/302 状态码,告诉浏览器去访问 Location 里的新地址,浏览器自动发起第二次 HTTP 请求。 _redirect_flag是布尔标记,用来标记本次响应是否需要执行重定向;如果标记为 true,就组装重定向响应,而不是返回文件内容。

10.开发muduo库的时候遇到的问题以及解决方法

S:手写 HTTP 服务器,状态机解析请求行,做超长请求防护。

T:防止超长请求攻击。

A:我写了代码,读不到完整一行时,判断缓冲区可读大小超过 MAX_LINE 返回 414。

后面测试发现防护存在漏洞:攻击者缓慢发送字符,不发送\r\n换行,缓冲区维持在 MAX_LINE 以内,持续占用 fd,造成慢速 DoS。 一开始我想把 MAX_LINE 调小,更早触发上限,但是测试发现这只是缓解,治标不治本。攻击者依旧可以一字节一字节慢慢发送,缓冲区永远达不到阈值。 所以我意识到,单纯靠缓冲区长度限制无法解决。

最终方案: ① 每次 socket 读取数据后都执行缓冲区长度校验;

② 使用项目里的时间轮定时器,给每个连接注册空闲超时任务;长时间收不到完整请求,直接关闭 fd 释放资源。 R:修复之后,既能正常处理 TCP 分包带来的半行数据,又可以抵御慢速 DoS 攻击。

11.什么是状态机?

12.http搭建遇到的问题总结

13.关于muduo库的线程安全问题

Muduo 每个 EventLoop 都有独立私有的任务队列 ,不存在所有 EventLoop 共用同一个全局任务池。 别的线程通过 runInLoop 向这个 loop 投递任务时,队列本身带互斥锁保护,push 操作线程安全。 但是任务回调内部访问的业务数据,muduo 不会自动加锁,业务数据的并发访问需要我们自己保证线程安全。

相关推荐
夏幻灵5 小时前
JavaScript this 面试:五种绑定规则、优先级与常见面试陷阱
开发语言·javascript·面试
Apipi*5 小时前
30天速通Linux 第六章信号及信号处理
linux·运维·信号处理
天启HTTP6 小时前
爬虫防封核心原理:IP轮换机制与风控规避逻辑
linux·服务器·网络·爬虫·tcp/ip
广州浮点FLOATLIC9 小时前
许可证服务器迁移后软件打不开:研发 IT 怎样定位连接问题
linux·服务器·数据库
BLUcoding9 小时前
接口服务公网超时排查记录:SecureRandom 阻塞问题分析与解决
java·linux·springboot·aes·securerandom
AIgorithmGEEK9 小时前
[Linux]从手写报头到内核套路:序列化、反序列化与自定义协议全链路
linux·运维·服务器·网络·序列化·反序列化
Nil2089 小时前
leetcode 139单词拆分
linux·运维·服务器
Starry-sky(jing)9 小时前
BUG: unable to handle kernel paging request 完整排查:dmesg 四要素与三路定罪
linux·运维·服务器·内核·排障
mounter6259 小时前
从硬件互连到操作系统变革:CXL 技术演进与 Linux 内核工程挑战
linux·运维·服务器
时间的拾荒人10 小时前
Qt 界面优化:绘图详解 —— 从基础图形到图片处理
开发语言·qt·面试