【Linux】HTTP协议深度解析(一):协议基础与请求响应格式

文章目录

    • HTTP协议深度解析(一):协议基础与请求响应格式
    • 一、HTTP协议是什么
      • [1.1 超文本传输协议](#1.1 超文本传输协议)
      • [1.2 HTTP的工作流程](#1.2 HTTP的工作流程)
      • [1.3 HTTP的特点](#1.3 HTTP的特点)
      • [1.4 HTTP与TCP的关系](#1.4 HTTP与TCP的关系)
    • 二、URL详解
      • [2.1 URL的组成](#2.1 URL的组成)
      • [2.2 协议部分](#2.2 协议部分)
      • [2.3 域名与端口](#2.3 域名与端口)
      • [2.4 路径部分](#2.4 路径部分)
      • [2.5 查询参数(Query String)](#2.5 查询参数(Query String))
      • [2.6 片段标识符(Fragment)](#2.6 片段标识符(Fragment))
    • 三、urlencode和urldecode
      • [3.1 为什么需要urlencode](#3.1 为什么需要urlencode)
      • [3.2 urlencode的规则](#3.2 urlencode的规则)
      • [3.3 实际例子](#3.3 实际例子)
      • [3.4 urldecode](#3.4 urldecode)
      • [3.5 在线工具](#3.5 在线工具)
    • 四、HTTP请求格式
      • [4.1 请求格式概览](#4.1 请求格式概览)
      • [4.2 首行(Request Line)](#4.2 首行(Request Line))
      • [4.3 Header(请求头)](#4.3 Header(请求头))
      • [4.4 Body(请求体)](#4.4 Body(请求体))
      • [4.5 完整示例](#4.5 完整示例)
    • 五、HTTP响应格式
      • [5.1 响应格式概览](#5.1 响应格式概览)
      • [5.2 首行(Status Line)](#5.2 首行(Status Line))
      • [5.3 Header(响应头)](#5.3 Header(响应头))
      • [5.4 Body(响应体)](#5.4 Body(响应体))
      • [5.5 完整示例](#5.5 完整示例)
    • [六、用TCP Socket验证HTTP协议](#六、用TCP Socket验证HTTP协议)
      • [6.1 最简单的HTTP服务器](#6.1 最简单的HTTP服务器)
      • [6.2 编译运行](#6.2 编译运行)
      • [6.3 浏览器测试](#6.3 浏览器测试)
      • [6.4 favicon.ico请求](#6.4 favicon.ico请求)
    • 七、Connection字段深度解析
      • [7.1 持久连接的必要性](#7.1 持久连接的必要性)
      • [7.2 HTTP/1.1的持久连接](#7.2 HTTP/1.1的持久连接)
      • [7.3 Connection字段的作用](#7.3 Connection字段的作用)
      • [7.4 测试持久连接](#7.4 测试持久连接)
    • 八、本篇总结
      • [8.1 核心要点](#8.1 核心要点)
      • [8.2 容易混淆的点](#8.2 容易混淆的点)

HTTP协议深度解析(一):协议基础与请求响应格式

💬 开篇:前面两篇完成了自定义应用层协议的设计与实现,从协议格式到序列化,从报文边界到网络计算器,掌握了协议设计的核心思想。但在实际工作中,我们很少从零设计协议,更多的是使用现成的成熟协议。HTTP协议就是互联网最重要的应用层协议之一,是浏览器与服务器通信的基础。这一篇从HTTP的基本概念讲起,深入剖析URL的构成、urlencode的必要性、HTTP请求和响应的格式,然后用TCP Socket手写一个HTTP服务器,用浏览器验证我们的理解。理解了HTTP,就理解了互联网的大部分通信机制。

👍 点赞、收藏与分享:这篇会把HTTP的核心知识讲透,从协议格式到实际验证,每个细节都会讲清楚。如果对你有帮助,请点赞收藏!

🚀 循序渐进:从HTTP是什么开始,到URL详解,到urlencode,到请求响应格式,到手写HTTP服务器验证,一步步理解HTTP的本质。


一、HTTP协议是什么

1.1 超文本传输协议

HTTP(HyperText Transfer Protocol,超文本传输协议)是互联网最重要的应用层协议。

核心作用:定义了客户端(如浏览器)与服务器之间如何通信,以交换或传输超文本(如HTML文档)。

你在浏览器地址栏输入http://www.baidu.com,按下回车,浏览器显示百度首页------这个过程就是HTTP协议在工作。

1.2 HTTP的工作流程

bash 复制代码
1. 浏览器(客户端)构造HTTP请求
   ↓
2. 通过TCP连接发送给服务器
   ↓
3. 服务器解析HTTP请求
   ↓
4. 服务器处理请求(读取文件、查询数据库等)
   ↓
5. 服务器构造HTTP响应
   ↓
6. 通过TCP连接发送给浏览器
   ↓
7. 浏览器解析HTTP响应
   ↓
8. 浏览器渲染HTML页面

1.3 HTTP的特点

无连接:http协议本身不维护连接状态/会话语义,每次请求都需要建立新的TCP连接(HTTP/1.0),或者复用连接(HTTP/1.1的持久连接)。

无状态:服务器不会保存客户端的状态信息。两次请求之间,服务器不知道是不是同一个客户端。

这个特点看起来是缺点,但其实是优点:

  • 简化了服务器设计
  • 提高了并发处理能力
  • 如果需要保存状态,可以用Cookie/Session等技术

基于请求-响应模型:"HTTP/1.x 基本是请求驱动;服务器不能在没有客户端请求的情况下凭空发起响应。但可以通过长连接、长轮询、SSE 等实现持续输出。"

1.4 HTTP与TCP的关系

HTTP是应用层协议,TCP是传输层协议。

bash 复制代码
应用层:HTTP协议(定义请求和响应的格式)
↓
传输层:TCP协议(可靠传输、流量控制、拥塞控制)
↓
网络层:IP协议(路由、寻址)
↓
链路层:以太网等(物理传输)

HTTP依赖TCP来保证数据可靠传输。浏览器发送HTTP请求时,先建立TCP连接(三次握手),然后在TCP连接上传输HTTP数据。


二、URL详解

2.1 URL的组成

URL(Uniform Resource Locator,统一资源定位符),俗称"网址"。

完整格式:

bash 复制代码
协议://域名:端口/路径?查询参数#片段标识符

示例:

bash 复制代码
http://www.example.com:8080/index.html?name=张三&age=20#section1

逐个拆解:

部分 含义
协议 http 使用HTTP协议
域名 www.example.com 服务器地址
端口 8080 服务器端口号
路径 /index.html 资源路径
查询参数 name=张三&age=20 键值对参数
片段标识符 section1 页面内锚点

2.2 协议部分

常见协议:

  • http:超文本传输协议(明文传输)
  • https:HTTP+SSL/TLS(加密传输)
  • ftp:文件传输协议
  • file:本地文件访问

示例:

http://www.baidu.com # HTTP协议
https://www.baidu.com # HTTPS协议

2.3 域名与端口

域名:服务器的"地址",会通过DNS解析成IP地址。

比如在一次解析中:
www.baidu.com → 14.215.177.38

端口:默认端口可以省略。

协议 默认端口
HTTP 80
HTTPS 443
FTP 21

所以:

bash 复制代码
[http://www.baidu.com](http://www.baidu.com)      等价于  [http://www.baidu.com:80](http://www.baidu.com:80)
[https://www.baidu.com](https://www.baidu.com)     等价于  [https://www.baidu.com:443](https://www.baidu.com:443)

2.4 路径部分

路径指定了要访问的资源。

bash 复制代码
[http://www.example.com/index.html](http://www.example.com/index.html)        # 访问根目录下的index.html
[http://www.example.com/images/logo.png](http://www.example.com/images/logo.png)   # 访问images目录下的logo.png
[http://www.example.com/api/users](http://www.example.com/api/users)         # 访问API接口

2.5 查询参数(Query String)

查询参数用?开头,多个参数用&连接。

格式:key1=value1&key2=value2

示例:

bash 复制代码
[http://www.example.com/search?keyword=Linux&page=2](http://www.example.com/search?keyword=Linux&page=2)

服务器会解析出:

bash 复制代码
keyword = "Linux"
page = "2"

2.6 片段标识符(Fragment)

片段标识符用#开头,用于定位页面内的锚点。

bash 复制代码
[http://www.example.com/article.html#section2](http://www.example.com/article.html#section2)

重要:片段标识符不会发送给服务器,只在浏览器端使用。

浏览器会:

  1. 请求http://www.example.com/article.html(不包含#section2)
  2. 收到页面后,自动滚动到id为section2的元素

三、urlencode和urldecode

3.1 为什么需要urlencode

URL中有些字符有特殊含义:

字符 含义
/ 路径分隔符
? 查询参数开始
& 参数分隔符
= 键值对分隔符
# 片段标识符开始
空格 分隔符

如果参数值包含这些字符,就会导致歧义。

例如:

bash 复制代码
[http://www.example.com/search?keyword=C++编程](http://www.example.com/search?keyword=C++编程)

问题:

  • 在 x-www-form-urlencoded 编码里,空格会编码成 +;因此如果参数值真的包含 +,应编码为 %2B,避免歧义。
  • URL 中非 ASCII 字符应按 UTF-8 bytes 做 percent-encoding,保证一致性与兼容性。

3.2 urlencode的规则

转义规则 :将需要转码的字符转为16进制,然后加上%前缀。

步骤:

  1. 获取字符的ASCII码(或UTF-8编码)
  2. 转成16进制
  3. 前面加上%

示例:

原字符 ASCII码 16进制 urlencode结果
空格 32 0x20 %20
+ 43 0x2B %2B
/ 47 0x2F %2F
? 63 0x3F %3F
& 38 0x26 %26
= 61 0x3D %3D

中文字符(UTF-8编码):

bash 复制代码
"编" 的UTF-8编码:E7 BC 96
urlencode结果:%E7%BC%96

"程" 的UTF-8编码:E7 A8 8B
urlencode结果:%E7%A8%8B

3.3 实际例子

原始URL:

bash 复制代码
[http://www.example.com/search?keyword=C++](http://www.example.com/search?keyword=C++) 编程

urlencode后:

bash 复制代码
[http://www.example.com/search?keyword=C%2B%2B%20%E7%BC%96%E7%A8%8B](http://www.example.com/search?keyword=C%2B%2B%20%E7%BC%96%E7%A8%8B)

拆解:

  • C:不需要转义,保持C
  • +:转义成%2B
  • +:转义成%2B
  • 空格:转义成%20
  • :转义成%E7%BC%96
  • :转义成%E7%A8%8B

3.4 urldecode

urldecode是urlencode的逆过程

步骤:

  1. 找到%开头的部分
  2. 提取后面两个16进制字符
  3. 转成10进制,得到ASCII码
  4. 转成字符

示例:

bash 复制代码
%2B → 0x2B → 43 → '+'
%20 → 0x20 → 32 → ' '(空格)
%E7%BC%96 → 编

3.5 在线工具

可以用在线工具测试urlencode:

bash 复制代码
# urlencode
echo -n "C++ 编程" | curl -Gso /dev/null -w %{url_effective} --data-urlencode @- "" | cut -c 3-

# 输出:C%2B%2B%20%E7%BC%96%E7%A8%8B

四、HTTP请求格式

4.1 请求格式概览

HTTP请求分为三部分:

bash 复制代码
[首行]\r\n
[Header1]: [Value1]\r\n
[Header2]: [Value2]\r\n
...\r\n
\r\n
[Body]

重要 :每行都以\r\n(回车换行)结尾,Header和Body之间有一个空行(\r\n\r\n)。

4.2 首行(Request Line)

格式:

bash 复制代码
[方法] [URL] [版本]\r\n

示例:

bash 复制代码
GET /index.html HTTP/1.1\r\n

拆解:

  • 方法:GET
  • URL:/index.html(只包含路径和查询参数,不包含协议、域名、端口)
  • 版本:HTTP/1.1

其他示例:

bash 复制代码
POST /api/login HTTP/1.1\r\n
GET /search?keyword=Linux HTTP/1.1\r\n

4.3 Header(请求头)

Header是键值对,格式:Key: Value\r\n

示例:

bash 复制代码
Host: www.example.com\r\n
User-Agent: Mozilla/5.0\r\n
Accept: text/html\r\n
Content-Length: 27\r\n
\r\n

每个Header一行,以\r\n结尾。Header部分结束后有一个空行(\r\n),表示Header结束。

4.4 Body(请求体)

Body是可选的,通常用于POST、PUT等方法传输数据。

如果有Body,Header中必须有Content-Length字段,表示Body的字节数。

示例(POST请求):

bash 复制代码
POST /api/login HTTP/1.1\r\n
Host: www.example.com\r\n
Content-Type: application/x-www-form-urlencoded\r\n
Content-Length: 27\r\n
\r\n
username=admin&password=123

Body内容:username=admin&password=123(27字节)

4.5 完整示例

一个完整的GET请求:

bash 复制代码
GET /search?keyword=Linux HTTP/1.1\r\n
Host: www.example.com\r\n
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36\r\n
Accept: text/html,application/xhtml+xml,application/xml\r\n
Accept-Encoding: gzip, deflate\r\n
Connection: keep-alive\r\n
\r\n

一个完整的POST请求:

bash 复制代码
POST /api/login HTTP/1.1\r\n
Host: www.example.com\r\n
Content-Type: application/x-www-form-urlencoded\r\n
Content-Length: 27\r\n
\r\n
username=admin&password=123

五、HTTP响应格式

5.1 响应格式概览

HTTP响应也分为三部分:

bash 复制代码
[首行]\r\n
[Header1]: [Value1]\r\n
[Header2]: [Value2]\r\n
...\r\n
\r\n
[Body]

格式和请求类似,只是首行不同。

5.2 首行(Status Line)

格式:

bash 复制代码
[版本] [状态码] [状态描述]\r\n

示例:

bash 复制代码
HTTP/1.1 200 OK\r\n

拆解:

  • 版本:HTTP/1.1
  • 状态码:200
  • 状态描述:OK(给人看的,程序只看状态码)

其他示例:

bash 复制代码
HTTP/1.1 404 Not Found\r\n
HTTP/1.1 500 Internal Server Error\r\n
HTTP/1.1 302 Found\r\n

5.3 Header(响应头)

格式和请求头相同。

示例:

bash 复制代码
Content-Type: text/html\r\n
Content-Length: 1024\r\n
Server: Apache/2.4.41\r\n
Date: Wed, 21 Oct 2023 07:28:00 GMT\r\n
\r\n

5.4 Body(响应体)

Body通常是HTML页面、JSON数据、图片等内容。

示例(返回HTML页面):

bash 复制代码
HTTP/1.1 200 OK\r\n
Content-Type: text/html\r\n
Content-Length: 52\r\n
\r\n
<html>
<body>
<h1>Hello World</h1>
</body>
</html>

Body内容:<html>...</html>(52字节)

5.5 完整示例

一个完整的200响应:

bash 复制代码
HTTP/1.1 200 OK\r\n
Server: nginx/1.18.0\r\n
Date: Wed, 21 Oct 2023 07:28:00 GMT\r\n
Content-Type: text/html\r\n
Content-Length: 52\r\n
Connection: keep-alive\r\n
\r\n
<html>
<body>
<h1>Hello World</h1>
</body>
</html>

一个完整的404响应:

bash 复制代码
HTTP/1.1 404 Not Found\r\n
Server: nginx/1.18.0\r\n
Date: Wed, 21 Oct 2023 07:28:00 GMT\r\n
Content-Type: text/html\r\n
Content-Length: 48\r\n
\r\n
<html>
<body>
<h1>404 Not Found</h1>
</body>
</html>

六、用TCP Socket验证HTTP协议

6.1 最简单的HTTP服务器

现在我们用TCP Socket写一个最简单的HTTP服务器,只返回"Hello World"。

示例为了演示格式,假设一次 read 读全;实际工程需要循环读直到读到完整 header/body。 同时我们这里简单起见,响应后就close,等价于短连接行为。

cpp 复制代码
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(int argc, char* argv[])
{
    if (argc != 3) {
        printf("Usage: %s [ip] [port]\n", argv[0]);
        return 1;
    }
    
    // 1. 创建socket
    int listenfd = socket(AF_INET, SOCK_STREAM, 0);
    if (listenfd < 0) {
        perror("socket");
        return 1;
    }
    
    // 2. bind
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = inet_addr(argv[1]);
    addr.sin_port = htons(atoi(argv[2]));
    
    int ret = bind(listenfd, (struct sockaddr*)&addr, sizeof(addr));
    if (ret < 0) {
        perror("bind");
        return 1;
    }
    
    // 3. listen
    ret = listen(listenfd, 10);
    if (ret < 0) {
        perror("listen");
        return 1;
    }
    
    printf("HTTP Server started on %s:%s\n", argv[1], argv[2]);
    
    // 4. 循环accept
    while (1) {
        struct sockaddr_in client_addr;
        socklen_t len = sizeof(client_addr);
        int clientfd = accept(listenfd, (struct sockaddr*)&client_addr, &len);
        if (clientfd < 0) {
            perror("accept");
            continue;
        }
        
        // 5. 读取请求
        char request[10240] = {0};
        ssize_t n = read(clientfd, request, sizeof(request) - 1);
        if (n < 0) {
            perror("read");
            close(clientfd);
            continue;
        }
        
        printf("===== Request =====\n%s\n", request);
        
        // 6. 构造响应
        const char* html = "<html><body><h1>Hello World</h1></body></html>";
        char response[1024];
        sprintf(response, 
                "HTTP/1.1 200 OK\r\n"
                "Content-Type: text/html\r\n"
                "Content-Length: %lu\r\n"
                "\r\n"
                "%s",
                strlen(html), html);
        
        // 7. 发送响应
        write(clientfd, response, strlen(response));
        
        // 8. 关闭连接
        close(clientfd);
    }
    
    return 0;
}

6.2 编译运行

bash 复制代码
gcc -o http_server http_server.c
./http_server 0.0.0.0 9090

输出:

bash 复制代码
HTTP Server started on 0.0.0.0:9090

6.3 浏览器测试

打开浏览器,输入:

bash 复制代码
http://127.0.0.1:9090

浏览器显示:

bash 复制代码
Hello World

服务器端打印:

bash 复制代码
===== Request =====
GET / HTTP/1.1
Host: 127.0.0.1:9090
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9
Accept-Encoding: gzip, deflate
Connection: keep-alive

成功了!我们用TCP Socket实现了一个HTTP服务器,浏览器能够正确解析我们返回的HTML页面。

6.4 favicon.ico请求

你可能注意到,浏览器实际发送了两个请求:

bash 复制代码
GET / HTTP/1.1
...

GET /favicon.ico HTTP/1.1
...

favicon.ico是什么

favicon.ico是网站的图标,显示在浏览器标签页上。浏览器会自动请求这个文件。

我们的服务器对所有请求都返回同样的HTML,所以第二个请求也会收到"Hello World",但浏览器发现不是图片格式,就忽略了。


七、Connection字段深度解析

7.1 持久连接的必要性

HTTP/1.0的工作方式:

bash 复制代码
1. 客户端发起TCP连接(三次握手)
2. 客户端发送HTTP请求
3. 服务器返回HTTP响应
4. 关闭TCP连接(四次挥手)

如果一个网页包含10张图片、5个CSS文件、3个JS文件,就要建立18个TCP连接。每个连接都要三次握手和四次挥手,开销巨大。

7.2 HTTP/1.1的持久连接

HTTP/1.1引入了持久连接(Persistent Connection),也叫长连接(Keep-Alive)。

bash 复制代码
1. 客户端发起TCP连接(三次握手)
2. 客户端发送请求1
3. 服务器返回响应1
4. 客户端发送请求2(复用同一个TCP连接)
5. 服务器返回响应2
6. ...
7. 客户端或服务器主动关闭连接(四次挥手)

优势

  • 减少了TCP连接建立和关闭的开销
  • 减少了网络拥塞(TCP慢启动)
  • 降低了延迟

7.3 Connection字段的作用

HTTP/1.0:默认短连接,如果要持久连接,需要显式设置:

bash 复制代码
Connection: keep-alive

HTTP/1.1:默认持久连接,如果要短连接,需要显式设置:

bash 复制代码
Connection: close

7.4 测试持久连接

修改我们的HTTP服务器,不要每次都close(clientfd),而是循环读取请求:

cpp 复制代码
while (1) {
    int clientfd = accept(...);
    
    // 循环处理同一个连接的多个请求
    while (1) {
        char request[10240] = {0};
        ssize_t n = read(clientfd, request, sizeof(request) - 1);
        if (n <= 0) break;  // 连接断开
        
        printf("Request:\n%s\n", request);
        
        // 构造响应
        char response[1024];
        sprintf(response, 
                "HTTP/1.1 200 OK\r\n"
                "Content-Type: text/html\r\n"
                "Content-Length: %lu\r\n"
                "Connection: keep-alive\r\n"  // 告诉客户端保持连接
                "\r\n"
                "%s",
                strlen(html), html);
        
        write(clientfd, response, strlen(response));
    }
    
    close(clientfd);
}

这样,客户端可以在同一个TCP连接上发送多个HTTP请求。


八、本篇总结

8.1 核心要点

HTTP协议基础

  • HTTP是应用层协议,定义了客户端与服务器的通信格式
  • 无连接、无状态、基于请求-响应模型
  • 依赖TCP协议保证可靠传输

URL详解

  • 格式:协议://域名:端口/路径?查询参数#片段标识符
  • 默认端口:HTTP 80、HTTPS 443
  • 查询参数用?开头,&分隔,键值对格式
  • 片段标识符不发送给服务器

urlencode/urldecode

  • 特殊字符需要转义(/、?、&、=、空格等)
  • 转义规则:字符→16进制→加%前缀
  • 中文字符按UTF-8编码转义

HTTP请求格式

  • 首行:方法 URL 版本
  • Header:键值对,每行\r\n结尾
  • 空行:\r\n
  • Body:可选,有Content-Length标识长度

HTTP响应格式

  • 首行:版本 状态码 状态描述
  • Header:键值对
  • 空行
  • Body:HTML、JSON、图片等

Connection字段

  • HTTP/1.0默认短连接,需要keep-alive
  • HTTP/1.1默认持久连接,可以close
  • 持久连接复用TCP连接,减少开销

8.2 容易混淆的点

  1. URL中的端口默认可以省略http://www.baidu.com实际访问的是http://www.baidu.com:80。

  2. 片段标识符不发送给服务器http://example.com/page#section,服务器只收到/page,不包含#section。

  3. urlencode为什么用%:因为%本身不是URL的特殊字符,可以安全使用作为转义标识。

  4. HTTP请求的URL只包含路径:GET /index.html HTTP/1.1,不包含协议、域名、端口(这些信息在Host字段中)。

  5. \r\n的必要性:HTTP协议规定行分隔符是\r\n,不能只用\n。这是历史原因(电传打字机需要回车+换行两个动作)。

  6. Connection: keep-alive和持久连接:HTTP/1.1默认就是持久连接,不需要显式设置keep-alive。只有HTTP/1.0需要。


💬 总结:这一篇从HTTP的基本概念讲起,详细剖析了URL的各个组成部分,解释了urlencode的必要性和规则,深入讲解了HTTP请求和响应的格式(首行、Header、Body),最后用TCP Socket手写了一个HTTP服务器并用浏览器验证。理解了HTTP的请求响应格式,就理解了浏览器和服务器通信的本质。下一篇会详细讲解HTTP方法(GET、POST等)、状态码、常见Header,以及它们的应用场景。
👍 点赞、收藏与分享:如果这篇帮你理解了HTTP协议的基础,请点赞收藏!下一篇会把HTTP的方法、状态码、Header全部讲透!

相关推荐
安科士andxe8 小时前
深入解析|安科士1.25G CWDM SFP光模块核心技术,破解中长距离传输痛点
服务器·网络·5g
寻寻觅觅☆10 小时前
东华OJ-基础题-106-大整数相加(C++)
开发语言·c++·算法
YJlio11 小时前
1.7 通过 Sysinternals Live 在线运行工具:不下载也能用的“云端工具箱”
c语言·网络·python·数码相机·ios·django·iphone
fpcc11 小时前
并行编程实战——CUDA编程的Parallel Task类型
c++·cuda
CTRA王大大11 小时前
【网络】FRP实战之frpc全套配置 - fnos飞牛os内网穿透(全网最通俗易懂)
网络
小白同学_C11 小时前
Lab4-Lab: traps && MIT6.1810操作系统工程【持续更新】 _
linux·c/c++·操作系统os
今天只学一颗糖11 小时前
1、《深入理解计算机系统》--计算机系统介绍
linux·笔记·学习·系统架构
2601_9491465311 小时前
Shell语音通知接口使用指南:运维自动化中的语音告警集成方案
运维·自动化
儒雅的晴天11 小时前
大模型幻觉问题
运维·服务器
testpassportcn12 小时前
AWS DOP-C02 認證完整解析|AWS DevOps Engineer Professional 考試
网络·学习·改行学it