最新资讯

  • C++进阶篇:006.Http服务器

C++进阶篇:006.Http服务器

2026-01-29 07:53:01 栏目:最新资讯 4 阅读

C++进阶篇:006.Http服务器

一、基本相关概念

1.1 万维网www

1> 万维网(world wide web):是一个大规模的、联机式的信息储藏所,简称web。能够实现使用链接的方式,方便地从一个站点访问到另一个站点,从而主动地按需获取丰富的信息

2> 超文本:包含了指向其它文档的链接的文本文档称为超文本,能够被浏览器所识别。一个超文本是由多个信息源组成,而这些信息源可以分布在世界各地,并且数量不受限制。超文本是万维网的基础。

3> 万维网使用的是BS模型,即浏览器服务器模型。浏览器向服务器发送请求,服务器响应浏览器并发送客户端所需要的超文本

4> URL(Uniform Resourse Locator):统一资源定位符,用来标识超文本在万维网中的唯一标识,表明了该超文本的信息,具有唯一性。网络访问中,就是依照此来进行请求以及响应的。

​ URL由四部分组成:协议://主机名端口号 / 路径

​ 例如:http://www.baidu.com.cn

​ 协议:指出使用的何种协议来获取万维网的文档,常用的协议就是http(超文本传输协议),://是规定格式,必须写上

​ 主机名:是万维网文档所在的主机域名(ip),通常以www开头,但也不是硬性要求,也可以直接使用主机的ip地址来代替

​ 端口号:就是该协议对应的端口号,对应http协议而言,默认的端口号是80

​ 路径:较长的字符串,超文本文档所在的路径

1.2 超文本传输协议http

1> 概念:HTTP定义了浏览器是怎样从万维网服务器中请求超文本,以及服务器如何把文档传递给浏览器的。

2> 从层次角度来说:HTTP是面向事务应用层协议,能够实现可靠的文件交换

​ 事务:指的是一系列的信息交换(建立连接、发送请求、响应请求。展示信息并断开请求),而这一系列的信息交换是一个不可分割的整体,要执行就全部执行结束,要不执行就全部不执行

​ 可靠:该协议是应用层协议,其传输层使用的是TCP协议进行的可靠传输

3> HTTP永远是客户端发起请求,服务器端进行响应。这样就限制了HTTP协议使用时,无法实现在客户端没有发起请求时,服务器主动向客户端发送消息。

4> HTTP协议是无状态的协议,同一个客户端的本次连接服务器和下一次的连接服务器没有任何联系,服务器没有记忆功能。

5> HTTP协议本身是无连接的,也就是说限制每个连接只能处理一个请求,服务器处理完客户端的请求并收到客户端的应答后就会立即断开连接。

6> 工作流程

1.3 超文本标记语言HTML

1.3.1 HTML的基本内容

1> HTML(HyperText Markup Language):超文本标记语言,是用来完成超文本文档的编写的。html并不是协议,而是万维网浏览器能够识别的一种语言、

2> 该语言中定义了需要使用的排版命令,这些命令我们称之为“标签”

3> 使用html语言编写的文档称为超文本,后缀为.html或者.htm

4> 浏览器主要解析的就是该语言编写出来的超文本,能将相关标签解析成界面

5> html编辑器可以是任意编辑器,如文本编辑器、VSCode、sublime等

1.3.2 常用标签

1> 标签格式:使用双尖括号包裹着关键字,通常成对出现

​ 内容

2> 标签分类

1、单标签:也称空标签 <标签名/>	例如:
2、双标签:成对出现 <标签名> 内容

3> 常用的标签

h1--h6:标题标签
p:段落标签
div:盒子标签
input:输入标签
...(更多可以参考菜鸟教程)
1.3.3 第一个HTML文件(VSCode版)

1> VSCode中创建一个后缀为.html的文档

2> 输入html:5 或者 ! 后按tab键补齐

3> 在扩展部分,加一个Live Server后,写完代码可以右键代码页面,选择Open with Live Server


DOCTYPE html>

<html lang="en">
    
<head>
    
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    
    <title>My first HTMLtitle>
    
head>

<body>
    
    
    <h1> 这是我的第一个界面,使用的是一级标题h1>
    
    <a href = "www.baidu.com">百度一下a>
    
    <br>
    账号:<input type="text">
    <br>
    密码:<input type="password">

    
body>

html>

二、HTTP版本

2.1 http1.0版本

从上世纪90年代开始,浏览器诞生后的第一个标准,是一个短连接的版本。

该版本的一个很大问题是:每发起一个请求,都要建立一次TCP的连接,而且是串行请求,做了很多无谓的TCP连接和断开,增加了开销,并且一般请求时使用的是明文模式,容易被攻击,安全性能比较低。

2.2 http1.1版本(正在使用的)

1> 在http1.0版本的基础上,增加了持续连接的功能。服务器在发送响应后的一段时间内,仍然保持这条连接,使同一个客户端和服务器可以在这条连接上继续后续的请求和响应工作。直到某一段主动断开连接或者长时间不响应时也会断开连接

2> http1.1版本支持两种工作模式

​ 非流水线方式:客户端在收到前一个响应之后,才能发出下一个请求

​ 流水线方式:客户端在收到前一个响应之前就能直接发送下一个请求

3> 特点:简单(报文首部和报文内容)、灵活易于拓展(请求方法和状态码没有固定死)

4> 不足:依然是无状态、明文传输不安全

5> http1.1版本所做的优化

1、使用长连接的方式,解决了1.0版本的短连接的性能问题:只要任意一端没有明确提出断开连接,则一直保持TCP的连接状态
2、使用管道网络传输:允许在同一个TCP连接中,建立多个管道,客户端可以发送多个请求,不需要等到服务器响应后才发送另一个请求,这样就提高了整体的响应效率,解决了请求的队头阻塞
   不足是:服务器端必须按照接受请求的顺序发送这些请求的响应,如果服务器在处理请求A花费了很长时间,那么后续的请求的处理,就都会被阻塞,这称为响应的队头阻塞
3、实际上HTTP1.1的管道化技术并不是默认开启的,而且很多浏览器几乎都不支持,所以,大家只需要知道HTTP1.1版本提供了该功能,但是并没有得到广泛应用

6> http1.1的瓶颈

1、头部巨大且重复:http头部会含有很多固定的字段,并且加起来会有几百字节甚至上千字节,未经压缩就直接发送
				大量的请求和响应报文中会有很多重复的字段:
				http协议是无状态的,想要记录之前的操作,在首部外加了一个cookie的技术,也会使得首部比较巨大
2、http1.1版本传输请求和响应的过程使用的是ASCII编码完成,而不是二进制编码
3、并发连接数是有限的,以谷歌为例,最大的并发连接数是6个,而且每个连接都要经过TCP的三次握手,以及TCP的慢启动过程
4、响应队头阻塞问题没有解决
5、不支持服务器推送过程,只能客户端请求,服务器响应

2.3 http2.0版本

1> 2015年推出了http2.0版本,目的是为了改善http的性能,并且兼容了http1.1版本。

2> http2.0版本只在应用层做了改变,传输层还是使用的TCP传输协议。http2.0把http分为【语义】和【语法】两部分,其中语义层不做改动,跟http1.1保持一致,但是在语法部分做了很多改动,基本上改变了HTTP的报文传输格式。

3> http2.0完成了头部压缩,http2.0使用了HPACK算法,发送的是压缩后的内容,这样就可以节约带宽,解决了http1.1版本的头部巨大且重复问题。HPACK算法将传输过程中进行的同一个TCP传输的内容进行合并,重复的内容不需要进行传输了,提高传输效率。

4> http2.0能够实现并发传输,引入了stream的概念,可以实现并发发送stream流,只需要建立一个TCP的连接,节约了多次建立连接过程中握手机制的时间。

5> http2.0实现了数据推送功能:服务器端和客户端双方都会建立一个stream,并且使用stream ID进行区分。客户端建立的是奇数号服务器建立的是偶数号。服务器推送数据时,会先发送PUSH_PROMISS帧,告诉客户端接下来哪个stream发送资源。

6> http2.0的不足

1、也存在响应队头阻塞问题
2、TCP的握手延时问题
3、网络迁移时,需要进行重新连接:服务器和客户端建立连接的四要素:源ip地址、源端口号、目的ip地址、目的端口号
总结:以上问题主要的原因是应用层使用的是TCP服务,无论http层再怎么设计都无法逃避,如果想要从根本上解决问题,那么就需要彻底改变传输层的相关协议,将传输层的TCp协议改成UDP协议,这就是http3.0的重要改革部分

2.4 http3.0版本

1> http3.0是最新推出的传输协议

2> http3.0将传输层的TCP协议更改成了UDP协议,使用的是基于UDP的QUIC协议

​ UDP:面向无连接的,不关心是否丢包,所以解决了队头阻塞问题

3> QUIC协议:基于UDP实现的,面向无连接的协议,也不需要进行三次握手和四次挥手,在协议中实现了类似于TCP的连接管理、拥塞控制、流量控制等相关操作。相当于将UDP的不可靠传输改成可靠的传输协议了

4> QUIC协议中也有一个stream的概念,保证数据的可靠性,每个stream数据报都有一个唯一的ID标识。当一个数据报一旦丢失后,该数据会被重传,不会影响其他数据报的传输

5> 能实现更快的连接建立:QUIC协议也需要进行握手连接,相当于将TCP的握手机制结合在一起,基于一个ID进行连接,而不是基于源ip地址、源端口号、目的ip地址、目的端口号

6> 不是基于四元组进行连接的,是通过一个stream ID完成,那么就可以实现在不同网络下的迁移

2.5 https版本(http1.1开始支持)

1> 为了传输的安全性,引入了HTTPS,加密的超文本传输协议

2> 在HTTP层和TCP层之间加入了TLS协议,该协议提供了信息加密、校验机制以及身份证数字证书

3> TLS协议需要进行四次握手机制

1、客户端向服务器随机数C、TLS协议版本号、密钥套件系列列表
2、服务器收到客户端信息后回复一个ACK
3、服务器再发送一个随机数S、确认TLS版本号和使用的密钥套件
4、客户端回复一个ACK

4> 注意:TLS的四次握手,是发生在TCP的三次握手建立连接之后执行的安全性检查,是一个耗时操作,但是确保了信息的安全性。

2.6 一个模型记住各个版本的http

三、HTTP报文格式

1> HTTP报文分为两类

​ 请求报文:从客户端向服务器发送的请求报文

​ 响应报文:从服务器向客户端发送的应答

2> 报文由三部分组成:开始行、首部行和实体主体

1、开始行:用于区分是请求报文还是响应报文
		请求报文中,开始行也称为请求行
		响应报文中,开始行也称为状态行
2、首部行:用来说明浏览器、服务器以及报文主体的一些信息
		首部行可以有很多行,也可以没有
		在每一个首部行都有一个首部的字段名和它的值,中间使用冒号隔开,每一行的首部行中间使用回车换行隔开
		整个首部行结束后,还有一个空行将首部行和后面的实体主体进行分隔
3、实体主体:在请求报文中一般不用。有时响应报文也可以没有

3.1 客户端请求报文格式

1> 请求行由三部分组成,分别是请求方法、URL和版本,中间使用空格隔开

2> 请求方法:就是对所请求的对象进行的操作,因此这些方法实际上也就是一些操作指令。因此,请求报文的类型是由它所指定的方法来决定的。

常用的请求方法:
1、GET:用来请求URL的资源,并返回实体主体
2、POST:向指定的资源提交数据并进行处理(例如提交的是表单或者上传文件)。数据被包含在实体主体部分。POST请求可能会导致新的资源的建立或者对已有资源的修改
3、HEAD:类似于GET请求,但是返回的是响应中的首部,没有内容主体
4、PUT:从客户端向服务器传送的指定的文档内容
5、DELETE:请求服务器去删除某些页面
6、OPTION:请求一些选项的信息
7、TRACE:用来进行环回测试使用的报文请求
8、CONNECT:HTTP/1.1版本中预留给能够将连接改为管道方式的代理服务

3> URL:统一资源定位符,就是要申请的资源路径

4> 版本:HTTP版本,目前常用的是HTTP1.1版本

5> CR和LF:回车和换行

6> 报文请求的实例

3.2 服务器响应报文格式

1> 响应报文的首部也称为状态行,也由三部分组成:分别是版本、状态码和解释状态码的短语,中间也使用空格隔开

2> 版本:就是HTTP版本

3> 状态码:状态码是由三位数字组成,第一个数字定义了响应的类别,共分为5类

1xx:指示信息---表示请求已经接收,继续处理
2xx:成功---表示请求已经被成功接收、理解以及处理。如:200表示成功
3xx:重定向---表示要完成请求必须要更进一步的操作。如:304
4xx:客户端错误---表示请求的语法错误或者请求无法实现。
	432:HTTP错误
	400:客户端请求有语法错误,不能被服务器所解析
	401:认证失败,请求未被接收
	403:服务器收到请求,但是拒绝提供服务
	404:请求的资源不存在,或者输入的URL有误
5xx:服务器错误---表示服务器未能实现合法的请求
	500:服务器发生了不可预测的错误
	503:服务器不能处理当前客户端的请求,一段时间后可能恢复正常

4> 实体主体:可以有可以无,如果服务器需要向客户端发送数据,则将数据放入到该处

5> 响应报文实例:

四、Mini型HTTP服务器

4.1 实现模型

4.2 源码

1> main.cpp

#include
#include"http.h"

//定义线程体函数
void *msg_request(void *arg)
{
    //解析传进来的客户顿的套接字文件描述符
    int sock = *(int *)arg;

    //调用信息处理函数,该函数是所有请求的入口
    handler_msg(sock);
    return NULL;
}

/*************************主程序******************************/
int main(int argc, const char *argv[])
{
    int port = 80;          //默认使用80端口号

    //判断是否手动传入端口号
    if(argc > 1)
    {
        port = atoi(argv[1]);
        //atoi:将给定的字符串转变为整数,参数是字符串(只能包含数字字符),返回值是整数
    }

    //初始化服务器
    //自定义函数:完成TCP服务器初始化操作   创建套接字-绑定端口号-监听
    //参数:端口号
    //返回值:服务器套接字
    int lis_socket = init_server(port);

    while(1)
    {
        struct sockaddr_in peer;            //接受客户端的地址信息结构体
        socklen_t len = sizeof(peer);       //接受长度

        //接收客户端的连接请求
        //返回的套接字就是服务器端创建出来的用于跟客户端进行通信的套接字文件描述符
        int sock = accept(lis_socket, (struct sockaddr *)&peer, &len);
        if(sock == -1)
        {
            perror("accept error");
            return -1;
        }

        printf("您有新的客户端发来连接请求了
");

        //创建一个分支线程用于跟客户端进行通信
        pthread_t tid = -1;
        if(pthread_create(&tid, NULL, msg_request, &sock) > 0)
        {
            printf("pthread_create error");
            return -1;
        }

        //将线程设置成分离态(否则会阻塞)
        pthread_detach(tid);
    }

    //关闭服务器
    close(lis_socket);


    return 0;
}

2> http.cpp

#include "http.h"
#include "custom_handle.h"
#include 

int init_server(int _port)
{
    //创建套接字
    int sock = socket(AF_INET, SOCK_STREAM, 0);
    if(sock == -1)
    {
        perror("socket error");
        return -1;
    }

    //端口号快速重用
    int reuse = 1;
    if(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) == -1)
    {
            perror("setsockopt error");
            return -1;
    }

    //绑定ip和端口号
    //填充地址信息结构体
    struct sockaddr_in local;
    local.sin_family = AF_INET;         //协议族
    local.sin_port = htons(_port);      //端口号
    local.sin_addr.s_addr = INADDR_ANY; //表示可以接收任意主机的连接请求

    //绑定工作
    if(bind(sock, (struct sockaddr *)&local, sizeof(local)) == -1)
    {
        perror("bind error");
        return -1;
    }

    //启动监听
    if(listen(sock, 128) == -1)
    {
        perror("listen error");
        return -1;
    }

    //程序执行至此,说明服务器创建成功
    return sock;
}

//自定义从客户端套接字中读取一行信息函数
int get_line(int sock, char *buf)
{
    char ch = '';         //读取一个字符
    int i = 0;              //填充变量,用于填充buf,所以从0开始
    int ret = 0;            //记录读取数据的返回值

    while(i < SIZE && ch != '
')
    {
        ret = recv(sock, &ch, 1, 0);
        if(ret > 0 && ch == '
')
        {
            //下一个字符可能是'
'
            int s = recv(sock, &ch, 1, MSG_PEEK);       //将下一个字符拿出来看看
            if(s > 0 && ch == '
')
            {
                recv(sock, &ch, 1, 0);      //将回车读取出来,放入ch中
            }else
            {
                ch = '
';                  //直接在ch中放入一个换行-
            }
        }

        //程序执行至此,表示该字符需要放入字符串中
        buf[i] = ch;        //将读取下来的字符放入数组中
        i++;                //继续填充下一个位置
    }
    buf[i] = '';          //将字符串补充完整
    return i;               //将字符数组中字符串实际长度返回

}


//定义清空头部的函数
static void clear_header(int sock)
{
    char buf[SIZE] = "";    //获取消息的容器
    int ret = 0;            //读取的个数
    do
    {
        ret = get_line(sock, buf);           //循环将每一行数据全部读取出来
    } while(ret != 1 && strcmp(buf, "
") != 0);
}


//定义展示404界面的函数
static void show_404(int sock)
{
    //将获取的消息头部全部清除掉,上面解析数据直解析了请求行
    clear_header(sock);

    //组装首部信息
    const char *msg = "HTTP/1.1 404 Not Found
";
    //发送首部
    send(sock, msg, strlen(msg), 0);
    send(sock, "
", strlen("
"), 0);      //发送一个空行,切记切记!!!否则数据可能会出问题

    //打开一个html页面文档
    struct stat st;     //定义一个文件状态结构体
    stat("../wwwroot/404.html", &st);              //获取wwwroot目录下404界面信息,主要使用该信息中文件大小的文件
    int fd = open("../wwwroot/404.html", O_RDONLY);//以只读的形式打开文件
    if(fd == -1)
    {
        perror("open 404 error");
        return;
    }

    //将整个文件发送出去
    //函数原型:ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count);
    //功能:将一个文件描述符中的数据发送到另一个文件描述符中
    //参数1:要被拷贝到的文件描述符
    //参数2:从哪个文件中拷贝
    //参数3:从该文件的那个位置开始拷贝
    //参数4:拷贝的文件大小
    sendfile(sock, fd, NULL, st.st_size);
    close(fd);
}


//定义处理错误信息的响应
//参数1:套接字文件描述符
//参数2:错误码
void echo_error(int sock, int err_code)
{
    //对错误码进行多分支选择
    switch(err_code)
    {
        case 403:
            break;
        case 404:
            show_404(sock);     //调用404界面
            break;
        case 405:
            break;
        case 500:
            break;
        default:
            break;
    }
}


//定义响应普通页面的函数
static int echo_www(int sock, const char *path, size_t s)
{
    //以只读的形式打开文件
    int fd = open(path, O_RDONLY);
    if(fd == -1)
    {
        perror("open error");
        return -1;
    }

    //组装响应首部
    const char *msg = "HTTP/1.1 200 OK
";
    send(sock, msg, strlen(msg), 0);        //发送给客户端网页
    send(sock, "
", strlen("
"), 0);  //发送空行

    //将整个文件发送给网页端
    if(sendfile(sock, fd, NULL, s) == -1)
    {
        echo_error(sock, 500);              //返回错误界面
        return -1;  
    }
    close(fd);
    return 0;
}


//如果是POST请求或者携带数据的GET请求,都需要手动书写逻辑进行处理
static int handle_request(int sock, const char *method, const char *path, const char *querry_string)
{
    char line[SIZE] = "";                   //存储一行数据
    int ret = 0;                            //接收返回结果
    int content_len = -1;                    //接收消息的内容长度

    //判断是否为GET请求
    if(strcasecmp(method, "GET") == 0)
    {
        //清空消息头部
        clear_header(sock);
    }else
    {
        //为post请求
        //获取POST请求的参数
        do
        {
            ret = get_line(sock, line);     //读取一行信息
            if(strncasecmp(line, "content-length", 14) == 0)
            {
                content_len = atoi(line + 16);  //获取请求的长度
            }
        } while(ret != 1 && (strcmp(line, "
") != 0));
    }

    //输出一些相关信息
    printf("method = %s
", method);                    //方法
    printf("querry_string = %s
", querry_string);      //请求内容
    printf("content_len = %d
", content_len);          //请求数据的长度

    char req_buf[SIZE] = "";                            //用于回复的消息

    //如果是POST方法,那么肯定携带请求数据,那么就需要把要请求的数据解析出来
    if(strcasecmp(method, "POST") == 0)
    {
        int len = recv(sock, req_buf, content_len, 0);  //将所需消息取出来
        printf("len = %d
", len);
        printf("req_buf = %s
", req_buf);
    }

    //发送给客户端消息
    const char *msg = "HTTP/1.1 200 OK

";        //回复报文响应首部
    send(sock, msg, strlen(msg), 0);

    //将请求交给自定义的代码来处理,这是业务逻辑
    parse_and_process(sock, querry_string, req_buf);

    return 0;
}



//用于处理客户端信息的函数的定义
int handler_msg(int sock)
{
    //定义容器存储客户端发来的数据
    char del_buf[SIZE] = "";

    //读取客户端发来的请求
    //通常我们使用recv接收客户端请求时,最后一个参数如果是0表示阻塞读取,并将数据读走
    //而最后一个参数为MSG_PEEK时,仅仅只是表示查看套接字中的数据,并不读走
    recv(sock, del_buf, SIZE, MSG_PEEK);

#if 1
    //看一看客户端发来的数据
    printf("--------------------------------------------------------------------
");
    printf("%s
", del_buf);
    printf("--------------------------------------------------------------------
");
#endif

    //接下来就是解析HTTP请求
    //获取请求行
    char buf[SIZE] = "";            //用于存储读取下来的客户端请求信息的一行

    //功能:获取套接字中的一行信息
    //参数1:套接字文件描述符
    //参数2:读取一行的字符串
    //返回值:当前行的长度
    int count = get_line(sock, buf);

    //程序执行至此,表示buf中已经存储了请求行的信息

    //接下来需要解析请求行中的请求方法以及请求url...
    char method[32] = "";           //存储请求方法的容器
    int k = 0;                      //填充请求方法

    //遍历请求行首部--->buf
    int i = 0;                      //用于遍历buf的循环变量
    for(i; i < count; i++)
    {
        //找到了任意一个字符
        if(isspace(buf[i]))         //如果该字符是空格,直接结束遍历
        {
            break;
        }

        method[k++] = buf[i];       //将字符放入方法串中
    }
    method[k] = '';               //将字符串补充完整
    //程序执行至此,method数组中就存储了请求方法

    //将空格跳过
    while(isspace(buf[i]) && i < SIZE)
    {
        i++;
    }
    //程序执行至此,i就记录了bf中后面的第一个非空字符串

    //判断请求方法是GET还是POST
    if(strcasecmp(method, "GET") != 0 && strcasecmp(method, "POST") != 0)
    {
        //说明该请求方法既不是GET也不是POST
        printf("method error
");
        // echo_error(sock, 405);      //向客户端回复一个错误页面
        close(sock);
        return -1;
    }

    //判断是否为POST请求
    int need_handle = 0;            //标识是否要进行手动处理界面,如果是1,则需要对数据处理,0表示不需要处理
    if(strcasecmp(method, "POST") == 0)
    {
        need_handle = 1;
    }

    //拿取要处理的url以及发送的数据(如果有?的话)
    char url[SIZE] = "";            //存储要解析的url
    int t = 0;                      //填充url字符串的变量
    char *querry_string = NULL;     //指向url中,是否有要处理的数据,如果有,则指向要处理的数据的起始地址

    for(i; i < SIZE; i++)           //继续向后遍历请求首部
    {
        //可能还会出现空格
        if(isspace(buf[i]))
        {
            break;                  //表示url读取结束
        }

        //此时表示buf[i]是一个url中的一个字符
        if(buf[i] == '?')           //说明请求中有数据要处理
        {
            //将资源路径保存在url字符数组中,并且使用querry_string指向附加数据
            querry_string = &url[t];
            querry_string ++;       //表示指向问号后的字符串
            url[t] = '';          //表示结束
        }else
        {
            url[t] = buf[i];        //其余普通字符,直接放入url容器中
        }

        t++;                        //继续填充下一个url内容
    }
    url[t] = '';                  //将字符串补充完整

    printf("url = %s
", url);
    printf("querry_string = %s
", querry_string);

    //程序执行至此,表示url数据也已经拿取下来了

    //如果是GET请求,并且有附带数据,也是需要手动处理的
    //例如:http://192.168.88.129:8080/index.html?tt=234    需要进行额外的处理
    if(strcasecmp(method, "GET") == 0 && querry_string != NULL)
    {
        need_handle = 1;
    }
    
    //我们可以把请求资源路径固定为 wwwroot 下的资源
    char path[SIZE] = "";           //用于确定要响应的文件路径
    sprintf(path, "../../wwwroot%s", url);//将url合成一个服务器中的路径
    //如果请求的地址没有任何携带资源,那么默认返回index.html
    if(path[strlen(path) - 1] == '/')
    {
        strcat(path, "index.html");
    }
    printf("path = %s
", path);


    //判断当前服务器中是否有该path
    struct stat st;                 //定义文件状态类型的结构体
    if(stat(path, &st) == -1)       //如果指定的文件存在,则会把该文件的信息放入st结构体中,如果不存在,函数返回-1
    {
        //说明要访问的文件不存在
        printf("can not find file
");
        echo_error(sock, 404);
        close(sock);
        return -1;
    }

    //程序执行至此,表示能够确定是否需要自己来处理后续逻辑了

    //如果是POST请求或者携带数据的GET请求,都需要手动书写逻辑进行处理
    if(need_handle == 1)
    {
        //调用处理请求函数
        //参数1:套接字文件描述符
        //参数2:请求方法
        //参数3:请求的路径
        //参数4:请求附带的数据
        handle_request(sock, method, path, querry_string);
    }else
    {
        //调用清除 请求首部剩余的内容
        clear_header(sock);
        //此时表示是GET请求,并且没有附加数据,则直接返回请求的界面即可
        echo_www(sock, path, st.st_size);
    }

    //表示所有请求都正常处理了
    close(sock);        //关闭客户端
    return 0;

}

3> custom_handle.cpp

#include "custom_handle.h"
#include 

#define KB 1024
#define HTML_SIZE (64*1024)

//处理求和的相关逻辑
static int handle_add(int sock, const char *req_buf)
{
    int num1, num2;         //存储传过来的两个数据

    //使用函数将数据解析出来

    sscanf(req_buf, ""data1=%ddata2=%d"", &num1, &num2);  
    printf("num1 = %d, num2 = %d", num1, num2);

    //封装应答包
    char reply_buf[HTML_SIZE];
    sprintf(reply_buf, "%d", num1 + num2);          //得到两数的和,并转换为字符串
    printf("reply_buf = %s
", reply_buf);

    //将数据发送到网页端
    send(sock, reply_buf, strlen(reply_buf), 0);

    return 0;
}


//定义有关处理登录界面的函数
int handle_login(int sock, char *req_buf)
{
    char reply_buf[HTML_SIZE] = "";             //定义用于回复消息的容器

    //解析数据
    char *uname = strstr(req_buf, "username="); //将uname指针锁定到账号的起始位置
    //将指针进行偏移(此时uname恰好在username=的前面)
    uname += strlen("username=");
    char *ptr = strstr(req_buf, "password=");   //锁定密码的位置
    *(ptr-1) = '';                            //将账号与密码分开,并将账号部分修改为C风格字符串

    //锁定密码
    char *passwd = ptr + strlen("password=");
    printf("账号:%s    密码:%s
", uname, passwd);

    //判断账号与密码是否匹配:登录成功的逻辑--->当账号和密码相等表示成功
    if(strcmp(uname, passwd) == 0)
    {
        //程序执行至此,表示登陆成功,此时可以跳转到首页
        sprintf(reply_buf, "", uname);        //用户名
        strcat(reply_buf, "");                      //要跳转的页面

        //消息已经组装成功,此时发给网页端
        send(sock, reply_buf, strlen(reply_buf), 0);
    }

    return 0;
}


//处理相关的数据使用的函数
int parse_and_process(int sock, const char *querry_string, char *req_buf)
{
    //先处理求和函数 :hello world  worl
    if(strstr(req_buf, "data1=") && strstr(req_buf, "data2="))
    {
        //说明这是要处理求和功能
        return handle_add(sock, req_buf);           //处理求和的功能
    }else if(strstr(req_buf, "username=") && strstr(req_buf, "password="))
    {
        //处理登录请求
        return handle_login(sock, req_buf);

    }else
    {
        //处理其他请求
    }

    return 0;
}

4> CMakeLists.txt

# 规定最小版本
cmake_minimum_required(VERSION 2.8)

# 项目名称
project(thttpd)

# 添加可执行文件
add_executable(thttpd.out main.cpp http.cpp custom_handle.cpp)

# 链接线程支持库
target_link_libraries(thttpd.out pthread)

5> http.h

#pragma once

#define SIZE 4096       //接收数据的大小

//声明初始化服务器函数
int init_server(int _port);

//声明消息处理函数,用于处理客户端发来的消息
int handler_msg(int sock);

6> custom_handle.h

#pragma once

//业务逻辑处理函数
int parse_and_process(int sock, const char *querry_string, char *req_buf);

strstr(req_buf, “data2=”))
{
//说明这是要处理求和功能
return handle_add(sock, req_buf); //处理求和的功能
}else if(strstr(req_buf, “username=”) && strstr(req_buf, “password=”))
{
//处理登录请求
return handle_login(sock, req_buf);

}else
{
    //处理其他请求
}

return 0;

}


4>  CMakeLists.txt

```cmake
# 规定最小版本
cmake_minimum_required(VERSION 2.8)

# 项目名称
project(thttpd)

# 添加可执行文件
add_executable(thttpd.out main.cpp http.cpp custom_handle.cpp)

# 链接线程支持库
target_link_libraries(thttpd.out pthread)

5> http.h

#pragma once

#define SIZE 4096       //接收数据的大小

//声明初始化服务器函数
int init_server(int _port);

//声明消息处理函数,用于处理客户端发来的消息
int handler_msg(int sock);

6> custom_handle.h

#pragma once

//业务逻辑处理函数
int parse_and_process(int sock, const char *querry_string, char *req_buf);

本文地址:https://www.yitenyun.com/1548.html

搜索文章

Tags

#ios面试 #ios弱网 #断点续传 #ios开发 #objective-c #ios #ios缓存 #服务器 #python #pip #conda #kubernetes #笔记 #平面 #容器 #linux #学习方法 #远程工作 香港站群服务器 多IP服务器 香港站群 站群服务器 #Trae #IDE #AI 原生集成开发环境 #Trae AI #人工智能 #微信 #分阶段策略 #模型协议 #运维 #学习 #科技 #深度学习 #自然语言处理 #神经网络 #华为云 #部署上线 #动静分离 #Nginx #新人首发 #harmonyos #docker #鸿蒙PC #github #git #物联网 #websocket #Conda # 私有索引 # 包管理 #进程控制 #开源 #fastapi #html #css #kylin #低代码 #爬虫 #音视频 #开发语言 #云原生 #iventoy #VmWare #OpenEuler #hadoop #hbase #hive #zookeeper #spark #kafka #flink #银河麒麟高级服务器操作系统安装 #银河麒麟高级服务器V11配置 #设置基础软件仓库时出错 #银河麒高级服务器系统的实操教程 #生产级部署银河麒麟服务系统教程 #Linux系统的快速上手教程 #数信院生信服务器 #Rstudio #生信入门 #生信云服务器 #后端 #数据库 #langchain #vscode #mobaxterm #计算机视觉 #内网穿透 #网络 #cpolar #分布式 #华为 #FTP服务器 #node.js #MobaXterm #ubuntu #缓存 #sql #AIGC #agi #word #umeditor粘贴word #ueditor粘贴word #ueditor复制word #ueditor上传word图片 #tcp/ip #qt #C++ #Dell #PowerEdge620 #内存 #硬盘 #RAID5 #http #项目 #高并发 #gemini #gemini国内访问 #gemini api #gemini中转搭建 #Cloudflare #RTP over RTSP #RTP over TCP #RTSP服务器 #RTP #TCP发送RTP #ARM服务器 # GLM-4.6V # 多模态推理 #多个客户端访问 #IO多路复用 #回显服务器 #TCP相关API #pytorch #AI编程 #pycharm #ssh #算法 #大数据 #jmeter #功能测试 #软件测试 #自动化测试 #职场和发展 #Harbor #unity #c# #游戏引擎 #mcu #flask #企业开发 #ERP #项目实践 #.NET开发 #C#编程 #编程与数学 #内存治理 #django #android #腾讯云 #前端 #nginx #serverless #diskinfo # TensorFlow # 磁盘健康 #散列表 #哈希算法 #数据结构 #c++ #leetcode #golang #java #redis #mysql #经验分享 #安卓 #性能优化 #web安全 #安全 #Ansible # 自动化部署 # VibeThinker #网络协议 #Ubuntu服务器 #硬盘扩容 #命令行操作 #VMware #儿童书籍 #儿童诗歌 #童话故事 #经典好书 #儿童文学 #好书推荐 #经典文学作品 #uni-app #小程序 #notepad++ #自动化 #ansible #vllm #大模型 #Streamlit #Qwen #本地部署 #AI聊天机器人 #ci/cd #jenkins #gitlab #ide #区块链 #测试用例 #生活 #我的世界 #prometheus #Android #Bluedroid #智能手机 #udp #everything #jar #需求分析 #数学建模 #2026年美赛C题代码 #2026年美赛 #centos #架构 #java-ee #文心一言 #AI智能体 #Ascend #MindIE #ModelEngine #spring boot #vue.js #mvp #个人开发 #设计模式 #aws #云计算 #DisM++ # 系统维护 #jvm #京东云 #语音识别 #ai #c语言 #stm32 #unity3d #游戏 #服务器框架 #Fantasy #elasticsearch #transformer #设备驱动 #芯片资料 #网卡 #信息与通信 #iphone #spring #AI写作 #凤希AI伴侣 #java大文件上传 #java大文件秒传 #java大文件上传下载 #java文件传输解决方案 #journalctl #程序人生 #科研 #博士 #AI #大模型学习 #wordpress #雨云 #LobeChat #vLLM #GPU加速 #MC #json #链表 #链表的销毁 #链表的排序 #链表倒置 #判断链表是否有环 #电脑 #阿里云 #课程设计 #SSH反向隧道 # Miniconda # Jupyter远程访问 #gpu算力 #grafana #asp.net大文件上传 #asp.net大文件上传下载 #asp.net大文件上传源码 #ASP.NET断点续传 #asp.net上传文件夹 #web #webdav #ping通服务器 #读不了内网数据库 #bug菌问答团队 #MCP #MCP服务器 #风控模型 #决策盲区 #epoll #高级IO #计算机网络 #网络安全 #php #VS Code调试配置 #javascript #windows #数据仓库 #面试 #AI论文写作工具 #学术论文创作 #论文效率提升 #MBA论文写作 #asp.net #react.js #1024程序员节 #LoRA # RTX 3090 # lora-scripts #fiddler #牛客周赛 #ddos #信息可视化 #claude code #codex #code cli #ccusage #数据集 #iBMC #UltraISO #LLM #银河麒麟 #系统升级 #信创 #国产化 #flutter #mmap #nio #编辑器 #金融 #mcp #金融投资Agent #Agent #研发管理 #禅道 #禅道云端部署 #中间件 #深度优先 #DFS #svn #n8n #RAID #RAID技术 #磁盘 #存储 #sizeof和strlen区别 #sizeof #strlen #计算数据类型字节数 #计算字符串长度 #进程 #操作系统 #进程创建与终止 #shell #ssl #ollama #llm #智能路由器 #企业微信 #信号处理 #tcpdump #机器学习 #embedding #RustDesk #IndexTTS 2.0 #本地化部署 #树莓派4b安装系统 #毕业设计 #车辆排放 #oracle #SA-PEKS # 关键词猜测攻击 # 盲签名 # 限速机制 #模版 #函数 #类 #笔试 #生信 #时序数据库 #Spring AI #STDIO协议 #Streamable-HTTP #McpTool注解 #服务器能力 #WEB #我的世界服务器搭建 #minecraft #蓝桥杯 #paddleocr #流量监控 #laravel #pencil #pencil.dev #设计 #Playbook #AI服务器 #sqlite #PyCharm # 远程调试 # YOLOFuse #CPU利用率 #RAG #全链路优化 #实战教程 #openresty #lua #流媒体 #NAS #飞牛NAS #监控 #NVR #EasyNVR #Triton # PyTorch # CUDA #SSH保活 #Miniconda #远程开发 #压力测试 #openlayers #bmap #tile #server #vue #SSH Agent Forwarding # 容器化 #eBPF #单片机 #嵌入式硬件 #arm开发 #openEuler #Hadoop #vuejs #chatgpt #搜索引擎 #nacos #银河麒麟aarch64 #uvicorn #uvloop #asgi #event #todesk #homelab #Lattepanda #Jellyfin #Plex #Emby #Kodi #TensorRT # Triton # 推理优化 #zabbix #信令服务器 #Janus #MediaSoup #鸿蒙 #MS #Materials #YOLO #建筑缺陷 #红外 #microsoft #数码相机 #SSH #X11转发 #debian #sqlserver #密码学 #改行学it #创业创新 #程序员创富 #鸭科夫 #逃离鸭科夫 #鸭科夫联机 #鸭科夫异地联机 #开服 #agent #ai大模型 #apache #risc-v #tdengine #制造 #涛思数据 #vue上传解决方案 #vue断点续传 #vue分片上传下载 #vue分块上传下载 #ms-swift # 一锤定音 # 大模型微调 #deepseek #adb #SSH公钥认证 # 安全加固 #claude #推荐算法 #cpp #tensorflow #arm #log #PowerBI #企业 #dify #测试工具 #opencv #数据挖掘 #screen 命令 #macos #驱动开发 #远程桌面 #远程控制 #bash #azure #目标检测 #DeepSeek #蓝耘智算 #版本控制 #Git入门 #开发工具 #代码托管 #ida #个人博客 #里氏替换原则 #nas #守护进程 #复用 #screen #ONLYOFFICE #MCP 服务器 #嵌入式 #毕设 #STUN # TURN # NAT穿透 #嵌入式编译 #ccache #distcc #es安装 #ui #cursor #PyTorch #模型训练 #星图GPU #rustdesk #p2p #postgresql #连接数据库报错 #Docker #IPv6 #DNS #YOLOFuse # Base64编码 # 多模态检测 #C# # REST API # GLM-4.6V-Flash-WEB #微信小程序 #源码 #闲置物品交易系统 #C #视频去字幕 #bootstrap #SPA #单页应用 #web3.py #swagger #IndexTTS2 # 阿里云安骑士 # 木马查杀 #visual studio code #prompt #YOLOv8 # 目标检测 # Docker镜像 #fpga开发 #jetty #麒麟OS #mariadb #计算机 #OPCUA #开源软件 #mamba #esp32教程 #tomcat #firefox #CMake #Make #C/C++ #Python #LangGraph #CLI #JavaScript #langgraph.json #rust #Anything-LLM #IDC服务器 #私有化部署 #算力一体机 #ai算力服务器 #raid #raid阵列 #青少年编程 # 高并发部署 #vps #rocketmq #simulink #matlab #intellij-idea #database #idea #学术写作辅助 #论文创作效率提升 #AI写论文实测 #JAVA #Java #电气工程 #PLC #selenium #webpack #几何学 #拓扑学 #rdp #AB包 #负载均衡 #海外服务器安装宝塔面板 #前端框架 #reactjs #web3 #maven #翻译 #开源工具 #ComfyUI # 推理服务器 #libosinfo #Dify #ARM架构 #鲲鹏 #1panel #vmware #集成测试 #微服务 #TCP #客户端 #DIY机器人工房 #性能 #优化 #DDR #RAM #select #windows11 #系统修复 #.net #大模型入门 #AI大模型 #酒店客房管理系统 #论文 #说话人验证 #声纹识别 #CAM++ #语言模型 #其他 #智慧校园解决方案 #智慧校园一体化平台 #智慧校园选型 #智慧校园采购 #智慧校园软件 #智慧校园专项资金 #智慧校园定制开发 #模型上下文协议 #MultiServerMCPC #load_mcp_tools #load_mcp_prompt #机器人 #typescript #npm #PTP_1588 #gPTP #wsl #硬件工程 #Windows #Jetty # CosyVoice3 # 嵌入式服务器 #gitea #结构体 #万悟 #联通元景 #智能体 #镜像 #scala #网站 #截图工具 #批量处理图片 #图片格式转换 #图片裁剪 #webrtc #idm #SMTP # 内容安全 # Qwen3Guard #健身房预约系统 #健身房管理系统 #健身管理系统 #Android16 #音频性能实战 #音频进阶 #Reactor #流程图 #论文阅读 #论文笔记 #扩展屏应用开发 #android runtime #SSE # AI翻译机 # 实时翻译 #gateway #Comate #Coze工作流 #AI Agent指挥官 #多智能体系统 #clickhouse #无人机 #Deepoc #具身模型 #开发板 #未来 #北京百思可瑞教育 #百思可瑞教育 #北京百思教育 #r-tree #聊天小程序 #scrapy #eclipse #spring cloud #servlet #UOS #海光K100 #统信 #CANN #wpf #NFC #智能公交 #服务器计费 #FP-增长 #Proxmox VE #虚拟化 #Fun-ASR # 语音识别 # WebUI #交互 #CUDA #GPU服务器 #8U #硬件架构 #部署 #NPU #昇腾300I DUO #浏览器自动化 #python #cosmic #Qwen3-14B # 大模型部署 # 私有化AI #c++20 #矩阵 #线性代数 #AI运算 #向量 #SSH免密登录 #vp9 #程序员 #H5 #跨域 #发布上线后跨域报错 #请求接口跨域问题解决 #跨域请求代理配置 #request浏览器跨域 #运维开发 #opc ua #opc #游戏机 #JumpServer #堡垒机 #LVDS #高速ADC #银河麒麟操作系统 #openssh #华为交换机 #信创终端 #东方仙盟 # GLM-TTS # 数据安全 #处理器 #API限流 # 频率限制 # 令牌桶算法 #上下文工程 #langgraph #意图识别 #飞牛nas #fnos #黑群晖 #虚拟机 #无U盘 #纯小白 #支付 #指针 #RK3576 #瑞芯微 #硬件设计 #振镜 #振镜焊接 #teamviewer #Gunicorn #WSGI #Flask #并发模型 #容器化 #性能调优 #蓝湖 #Axure原型发布 #vim #gcc #yum #ESP32 #传感器 #MicroPython #ambari #jupyter #Linux #Socket网络编程 #单元测试 #ai编程 #llama #ceph #muduo库 #uv #uvx #uv pip #npx #Ruff #pytest #数据恢复 #视频恢复 #视频修复 #RAID5恢复 #流媒体服务器恢复 #SRS #直播 #milvus #springboot #知识库 #web server #请求处理流程 #910B #昇腾 #UDP套接字编程 #UDP协议 #网络测试 #chrome #RSO #机器人操作系统 #glibc #Anaconda配置云虚拟环境 #MQTT协议 #C语言 #Host #渗透测试 #SSRF #集成学习 #https #系统架构 #fabric #可信计算技术 #winscp #openHiTLS #TLCP #DTLCP #商用密码算法 #政务 #分类 # 双因素认证 #powerbi #服务器繁忙 #Clawdbot #个人助理 #数字员工 #LabVIEW知识 #LabVIEW程序 #LabVIEW功能 #labview #KMS #slmgr #宝塔面板部署RustDesk #RustDesk远程控制手机 #手机远程控制 #媒体 #连锁药店 #连锁店 #puppeteer #spine #POC #问答 #交付 #智能家居 #xlwings #Excel #mybatis # keep-alive #系统安全 #迁移重构 #数据安全 #漏洞 #代码迁移 #ipmitool #BMC #restful #ajax #nfs #iscsi #移动端h5网页 #调用浏览器摄像头并拍照 #开启摄像头权限 #拍照后查看与上传服务器端 #摄像头黑屏打不开问题 #范式 #数模美赛 #ecmascript #elementui #kmeans #聚类 #文件管理 #文件服务器 #文件IO #输入输出流 # 大模型 # 模型训练 #scanf #printf #getchar #putchar #cin #cout #大语言模型 #pandas #matplotlib #ET模式 #非阻塞 #高并发服务器 #Smokeping #策略模式 #pve #OSS #duckdb #全能视频处理软件 #视频裁剪工具 #视频合并工具 #视频压缩工具 #视频字幕提取 #视频处理工具 #多模态 #微调 #超参 #LLamafactory #企业级存储 #网络设备 #zotero #WebDAV #同步失败 #代理模式 #cesium #可视化 #工具集 #大模型应用 #API调用 #PyInstaller打包运行 #服务端部署 #数据分析 #排序算法 #jdk #排序 #欧拉 #aiohttp #asyncio #异步 #软件 #本地生活 #电商系统 #商城 #SMP(软件制作平台) #EOM(企业经营模型) #应用系统 #VoxCPM-1.5-TTS # 云端GPU # PyCharm宕机 # 模型微调 #数组 #儿童AI #图像生成 #麒麟 #.netcore # 水冷服务器 # 风冷服务器 #tornado # IndexTTS 2.0 # 自动化运维 #能源 #Aluminium #Google #大模型部署 #mindie #大模型推理 #业界资讯 #n8n解惑 #Go并发 #高并发架构 #Goroutine #系统设计 #Tracker 服务器 #响应最快 #torrent 下载 #2026年 #Aria2 可用 #迅雷可用 #BT工具通用 #net core #kestrel #web-server #asp.net-core #AI技术 #Shiro #反序列化漏洞 #CVE-2016-4437 #大模型开发 #elk #rabbitmq #Zabbix #CosyVoice3 #语音合成 #esp32 arduino #HistoryServer #Spark #YARN #jobhistory #产品运营 #联机教程 #局域网联机 #局域网联机教程 #局域网游戏 #EMC存储 #存储维护 #NetApp存储 #模拟退火算法 #简单数论 #埃氏筛法 #mongodb #x86_64 #数字人系统 #5G #汇编 #yolov12 #研究生life #文件传输 #电脑文件传输 #电脑传输文件 #电脑怎么传输文件到另一台电脑 #电脑传输文件到另一台电脑 #eureka #xss #rtsp #转发 #Termux #Samba #SSH别名 #三维 #3D #三维重建 #asp.net上传大文件 #土地承包延包 #领码SPARK #aPaaS+iPaaS #数字化转型 #智能审核 #档案数字化 #CVE-2025-61686 #路径遍历高危漏洞 #ShaderGraph #图形 #IntelliJ IDEA #Spring Boot #neo4j #NoSQL #SQL #Llama-Factory # 大模型推理 #VMware Workstation16 #服务器操作系统 #log4j #信创国产化 #达梦数据库 #边缘计算 #pdf #HeyGem # 服务器IP # 端口7860 #大模型教程 # 代理转发 # 跳板机 #GPU #AutoDL ##租显卡 #echarts # 远程访问 # 服务器IP配置 #进程等待 #wait #waitpid #VibeVoice # 语音合成 # 云服务器 #游戏美术 #技术美术 #游戏策划 #游戏程序 #用户体验 #阻塞队列 #生产者消费者模型 #服务器崩坏原因 #web服务器 #可撤销IBE #服务器辅助 #私钥更新 #安全性证明 #双线性Diffie-Hellman # 公钥认证 #markdown #建站 #结构与算法 # GPU租赁 # 自建服务器 #代理 #H5网页 #网页白屏 #H5页面空白 #资源加载问题 #打包部署后网页打不开 #HBuilderX #CTF #TLS协议 #HTTPS #漏洞修复 #运维安全 #VMWare Tool #遛狗 #ue5 #MinIO服务器启动与配置详解 #平板 #零售 #交通物流 #智能硬件 #arm64 #SSH复用 # 远程开发 #autosar #插件 #DHCP #心理健康服务平台 #心理健康系统 #心理服务平台 #心理健康小程序 # 远程运维 #注入漏洞 #nvidia #DAG #串口服务器 #Modbus #MOXA #GATT服务器 #蓝牙低功耗 #服务器解析漏洞 # ControlMaster #硬件 #safari #网路编程 #百万并发 #memory mcp #Cursor #intellij idea #WinDbg #Windows调试 #内存转储分析 #cnn #googlecloud #重构 #vnstat # 远程连接 #计组 #数电 #大剑师 #nodejs面试题 #C2000 #TI #实时控制MCU #AI服务器电源 # 树莓派 # ARM架构 #攻防演练 #Java web #红队 #Xshell #Finalshell #生物信息学 #组学 #memcache #GB28181 #SIP信令 #SpringBoot #视频监控 #SSH跳板机 # Python3.11 #WT-2026-0001 #QVD-2026-4572 #smartermail #UDP的API使用 #TTS私有化 # IndexTTS # 音色克隆 #智能一卡通 #门禁一卡通 #梯控一卡通 #电梯一卡通 #消费一卡通 #一卡通 #考勤一卡通 #ranger #MySQL8.0 #统信UOS #win10 #qemu # Connection refused #智能体来了 #智能体对传统行业冲击 #行业转型 #AI赋能 #系统管理 #服务 #数据采集 #浏览器指纹 #Modbus-TCP #视觉检测 #visual studio #screen命令 #源代码管理 #Nacos #gRPC #注册中心 #win11 #chat #黑客技术 #网安应急响应 #edge #迭代器模式 #观察者模式 #管道Pipe #system V #微PE # GLM # 服务连通性 #iot #求职招聘 #SAP #ebs #metaerp #oracle ebs #智慧城市 # 高并发 #c #YOLO26 #muduo #TcpServer #accept #LangFlow # 轻量化镜像 # 边缘计算 #国产化OS #实时音视频 #SSH跳转 #postman #go # GPU集群 #勒索病毒 #勒索软件 #加密算法 #.bixi勒索病毒 #数据加密 #超算服务器 #算力 #高性能计算 #仿真分析工作站 #计算几何 #斜率 #方向归一化 #叉积 #samba #硬盘克隆 #DiskGenius # 批量管理 #vivado license #CVE-2025-68143 #CVE-2025-68144 #CVE-2025-68145 #excel #html5 #weston #x11 #x11显示服务器 #copilot #音乐分类 #音频分析 #ViT模型 #Gradio应用 #IO #hibernate #ArkUI #ArkTS #鸿蒙开发 #手机h5网页浏览器 #安卓app #苹果ios APP #手机电脑开启摄像头并排查 #JNI #CPU #测评 #CCE #Dify-LLM #Flexus #sentinel #Ubuntu #ESP32编译服务器 #Ping #DNS域名解析 #麦克风权限 #访问麦克风并录制音频 #麦克风录制音频后在线播放 #用户拒绝访问麦克风权限怎么办 #uniapp 安卓 苹果ios #将音频保存本地或上传服务器 #YOLO11 #Node.js # child_process #面向对象 #基础语法 #标识符 #常量与变量 #数据类型 #运算符与表达式 #运维工具 #动态规划 #网络攻击模型 #pyqt #dlms #dlms协议 #逻辑设备 #逻辑设置间权限 #Discord机器人 #云部署 #程序那些事 #r语言 #scikit-learn #随机森林 #安全威胁分析 #仙盟创梦IDE #GLM-4.6V-Flash-WEB # AI视觉 # 本地部署 #服务器IO模型 #非阻塞轮询模型 #多任务并发模型 #异步信号模型 #多路复用模型 #前端开发 # 黑屏模式 # TTS服务器 #自由表达演说平台 #演说 #领域驱动 #Claude #STDIO传输 #SSE传输 #WebMVC #WebFlux #Linly-Talker # 数字人 # 服务器稳定性 #flume #3d #主板 #总体设计 #电源树 #框图 #Minecraft #Minecraft服务器 #PaperMC #我的世界服务器 #kong #Kong Audio #Kong Audio3 #KongAudio3 #空音3 #空音 #中国民乐 #工业级串口服务器 #串口转以太网 #串口设备联网通讯模块 #串口服务器选型 #零代码平台 #AI开发 #UDP #入侵 #日志排查 #传统行业 #国产开源制品管理工具 #Hadess #一文上手 #Spring AOP #环境搭建 #gnu #小艺 #搜索 #人大金仓 #Kingbase #软件工程 #产品经理 #就业 #ipv6 #租显卡 #训练推理 #图像识别 #ffmpeg #多进程 #python技巧 #双指针 #国产操作系统 #V11 #kylinos #KMS激活 # 硬件配置 #wps #Java程序员 #Java面试 #后端开发 #Spring源码 #Spring #CSDN #numpy #composer #symfony #java-zookeeper #Langchain-Chatchat # 国产化服务器 # 信创 #coffeescript #pjsip #Syslog #系统日志 #日志分析 #日志监控 #Autodl私有云 #深度服务器配置 #实体经济 #商业模式 #软件开发 #数智红包 #商业变革 #创业干货 #人脸识别sdk #视频编解码 #人脸识别 #blender #warp #AI生成 # outputs目录 # 自动化 #ZooKeeper #ZooKeeper面试题 #面试宝典 #深入解析 #Prometheus #FASTMCP #React安全 #漏洞分析 #Next.js #Puppet # IndexTTS2 # TTS #内存接口 # 澜起科技 # 服务器主板 # 显卡驱动备份 #交换机 #三层交换机 #vue3 #人脸核身 #活体检测 #身份认证与人脸对比 #微信公众号 #高斯溅射 #AI智能棋盘 #Rock Pi S #高仿永硕E盘的个人网盘系统源码 #MC群组服务器 #广播 #组播 #并发服务器 #ip #云开发 #云服务器 #个人电脑 #gpu #nvcc #cuda #unix #编程 #c++高并发 #支持向量机 #CS2 #debian13 #BoringSSL #企业存储 #RustFS #对象存储 #高可用 #VPS #搭建 #递归 #线性dp #农产品物流管理 #物流管理系统 #农产品物流系统 #农产品物流 #RXT4090显卡 #RTX4090 #深度学习服务器 #硬件选型 # ARM服务器 # 鲲鹏 #ssm #http头信息 #群晖 #音乐 #uip #SQL注入主机 #k8s #音诺ai翻译机 #AI翻译机 # Ampere Altra Max #sklearn # 权限修复 #考研 #模块 #TCP服务器 #开发实战 #全文检索 #SMARC #ARM #树莓派 #温湿度监控 #WhatsApp通知 #IoT #MySQL #空间计算 #原型模式 #devops #戴尔服务器 #戴尔730 #装系统 #汽车 #文件上传漏洞 #junit #L2C #勒让德到切比雪夫 #Kylin-Server #服务器安装 #ThingsBoard MCP #多线程 #性能调优策略 #双锁实现细节 #动态分配节点内存 #nosql # 智能运维 # 性能瓶颈分析 #vncdotool #链接VNC服务器 #如何隐藏光标 #数据访问 #A2A #GenAI # 服务器IP访问 # 端口映射 #HBA卡 #RAID卡 #bug #大学生 #大作业 #门禁 #梯控 #智能梯控 #电梯 #电梯运力 #电梯门禁 #程序开发 #程序设计 #计算机毕业设计 #自动化运维 #C++ UA Server #SDK #跨平台开发 #FHSS #bond #服务器链路聚合 #网卡绑定 #算力建设 #dba #mssql #性能测试 #LoadRunner #智能制造 #供应链管理 #工业工程 #库存管理 # ProxyJump #nodejs #TFTP #outlook #错误代码2603 #无网络连接 #2603 #机器视觉 #6D位姿 #SSH密钥 #练习 #基础练习 #循环 #九九乘法表 #计算机实现 #数字孪生 #三维可视化 #dynadot #域名 #ETL管道 #向量存储 #数据预处理 #DocumentReader #工厂模式 #esb接口 #走处理类报异常 #N8N #海外短剧 #海外短剧app开发 #海外短剧系统开发 #短剧APP #短剧APP开发 #短剧系统开发 #海外短剧项目 #b树 #RK3588 #RK3588J #评估板 #核心板 #嵌入式开发 #le audio #蓝牙 #低功耗音频 #通信 #连接 #smtp #smtp服务器 #PHP #银河麒麟部署 #银河麒麟部署文档 #银河麒麟linux #银河麒麟linux部署教程 #声源定位 #MUSIC #windbg分析蓝屏教程 #Buck #NVIDIA #交错并联 #DGX #PyTorch 特性 #动态计算图 #张量(Tensor) #自动求导Autograd #GPU 加速 #生态系统与社区支持 #与其他框架的对比 #AI视频创作系统 #AI视频创作 #AI创作系统 #AI视频生成 #AI工具 #文生视频 #AI创作工具 #ServBay #SFTP #安全架构 #AI 推理 #NV #npu #anaconda #虚拟环境 # OTA升级 # 黄山派 #ansys #ansys问题解决办法 # 网络延迟 #远程软件 #WRF #WRFDA #HarmonyOS #视频 #代理服务器 #ngrok #sql注入 #超时设置 #客户端/服务器 #网络编程 #挖矿 #Linux病毒 #turn #机器人学习 # IP配置 # 0.0.0.0 #雨云服务器 #教程 #MCSM面板 #Apple AI #Apple 人工智能 #FoundationModel #Summarize #SwiftUI # 服务器配置 # GPU #跳槽 #galeweather.cn #高精度天气预报数据 #光伏功率预测 #风电功率预测 #高精度气象 #视觉理解 #Moondream2 #多模态AI #线性回归 #路由器 #Gateway #认证服务器集成详解 #CA证书 #uniapp #合法域名校验出错 #服务器域名配置不生效 #request域名配置 #已经配置好了但还是报错 #uniapp微信小程序 #框架搭建 #状态模式 #AI-native #Tokio #华为od #华为机试 #react native #贴图 #材质 #设计师 #TTS # 键鼠锁定 #agentic bi #ASR #SenseVoice #论文复现 #opc模拟服务器 #远程连接 #mtgsig #美团医药 #美团医药mtgsig #美团医药mtgsig1.2 #工程设计 #预混 #扩散 #燃烧知识 #层流 #湍流 #知识 #量子计算 #WinSCP 下载安装教程 #FTP工具 #服务器文件传输 # 批量部署 #JT/T808 #车联网 #车载终端 #模拟器 #仿真器 #开发测试 #证书 #服务器线程 # SSL通信 # 动态结构体 #node #后端框架 #protobuf #报表制作 #职场 #数据可视化 #用数据讲故事 #语音生成 #Keycloak #Quarkus #AI编程需求分析 #lvs # 数字人系统 # 远程部署 #canvas层级太高 #canvas遮挡问题 #盖住其他元素 #苹果ios手机 #安卓手机 #调整画布层级 #LE Audio #BAP #MCP服务器注解 #异步支持 #方法筛选 #声明式编程 #自动筛选机制 #AITechLab #cpp-python #CUDA版本 #参数估计 #矩估计 #概率论 #gmssh #宝塔 #漏洞挖掘 #Exchange #小智 #free #vmstat #sar #系统安装 #铁路桥梁 #DIC技术 #箱梁试验 #裂纹监测 #四点弯曲 #目标跟踪 #可再生能源 #绿色算力 #风电 #ARM64 # DDColor # ComfyUI #节日 #MinIO #express #cherry studio #单例模式 #TRO #TRO侵权 #TRO和解 #地理 #遥感 #Fluentd #Sonic #日志采集 #taro #AI应用编程 #游戏服务器断线 #若依 #期刊 #SCI #EN4FE #Archcraft #AI Agent #开发者工具 #计算机外设 #Karalon #AI Test #图论 #okhttp #电子电气架构 #系统工程与系统架构的内涵 #自动驾驶 #Routine #健康医疗 #remote-ssh #glances #工程实践 #强化学习 #策略梯度 #REINFORCE #蒙特卡洛 #AI应用 #百度 #ueditor导入word #高考 #轻量化 #低配服务器 #gpt #API #阿里云RDS #Linux多线程 #bigtop #hdp #hue #kerberos #Beidou #北斗 #SSR #寄存器 #docker安装seata #信息安全 #信息收集 #Rust #poll #vrrp #脑裂 #keepalived主备 #高可用主备都持有VIP #H3C #dubbo #项目申报系统 #项目申报管理 #项目申报 #企业项目申报 #生产服务器问题查询 #日志过滤 # AI部署 #语义搜索 #嵌入模型 #Qwen3 #AI推理 #材料工程 #智能电视 #VMware创建虚拟机 #远程更新 #缓存更新 #多指令适配 #物料关联计划 #挖漏洞 #攻击溯源 #stl #IIS Crypto #tcp/ip #网络 #编程助手 #m3u8 #HLS #移动端H5网页 #APP安卓苹果ios #监控画面 直播视频流 #DooTask #决策树 #防毒面罩 #防尘面罩 #sglang #运营 #UEFI #BIOS #Legacy BIOS #Socket #程序定制 #毕设代做 #课设 #wireshark #UDP服务器 #recvfrom函数 # 服务器迁移 # 回滚方案 #身体实验室 #健康认知重构 #系统思维 #微行动 #NEAT效应 #亚健康自救 #ICT人 #开关电源 #热敏电阻 #PTC热敏电阻 #KMS 激活 #webgl #云计算运维 #高精度农业气象 #VSCode # SSH #日志模块 #Coturn #TURN #ICE #文本生成 #CPU推理 #WAN2.2 #银河麒麟服务器系统 #国产PLM #瑞华丽PLM #瑞华丽 #PLM #dash #正则表达式 # HiChatBox # 离线AI #人形机器人 #人机交互 #xml #区间dp #贪心算法 #二进制枚举 #短剧 #短剧小程序 #短剧系统 #微剧 #统信操作系统 #DDD #tdd #I/O模型 #并发 #水平触发、边缘触发 #多路复用 #CNAS #CMA #程序文件 #数据报系统 # GPU服务器 # tmux #网络安全大赛 #磁盘配额 #存储管理 #形考作业 #国家开放大学 #系统运维 #idc #题解 #图 #dijkstra #迪杰斯特拉 #实时检测 #卷积神经网络 #lucene #云服务器选购 #Saas #线程 #NSP #下一状态预测 #aigc # Qwen3Guard-Gen-8B #HarmonyOS APP #旅游 #密码 #具身智能 #spring ai #oauth2 #Cpolar #国庆假期 #服务器告警 #经济学 #rtmp #dreamweaver #nmodbus4类库使用教程 #docker-compose #晶振 #AI电商客服 # 局域网访问 # 批量处理 #resnet50 #分类识别训练 #运维 #cascadeur # 高温监控 #OpenManage #IFix #fs7TF #hdfs #华为od机试 #华为od机考 #华为od最新上机考试题库 #华为OD题库 #华为OD机试双机位C卷 #od机考题库 #AI+ #coze #AI入门 #ROS #React #Next #CVE-2025-55182 #RSC # 环境迁移 #OBC #gerrit #隐私合规 #网络安全保险 #法律风险 #风险管理 #FL Studio #FLStudio #FL Studio2025 #FL Studio2026 #FL Studio25 #FL Studio26 #水果软件 #xshell #host key #内网 #clawdbot #AI工具集成 #容器化部署 #分布式架构 #快递盒检测检测系统 #Matrox MIL #二次开发 #rsync # 数据同步 #图像处理 #vertx #vert.x #vertx4 #runOnContext #CMC #分布式数据库 #集中式数据库 #业务需求 #选型误 #claudeCode #content7 #工作 #懒汉式 #恶汉式 #odoo #网络配置实战 #Web/FTP 服务访问 #计算机网络实验 #外网访问内网服务器 #Cisco 路由器配置 #静态端口映射 #网络运维 #防火墙 # 串口服务器 # NPort5630 #appche #YOLO识别 #YOLO环境搭建Windows #YOLO环境搭建Ubuntu #服务器开启 TLS v1.2 #IISCrypto 使用教程 #TLS 协议配置 #IIS 安全设置 #服务器运维工具 #OpenHarmony #CS336 #Assignment #Experiments #TinyStories #Ablation #Python办公自动化 #Python办公 #ftp #sftp #星际航行 #cpu #套接字 #I/O多路复用 #字节序 #鼠大侠网络验证系统源码 #AI部署 # ms-swift #PN 结 #RWK35xx #语音流 #实时传输 #ossinsight #超算中心 #PBS #lsf #反向代理 #adobe #数据迁移 #测速 #iperf #iperf3 #pxe #cocos2d #图形渲染 #fork函数 #进程创建 #进程终止 #分子动力学 #化工仿真 #session #静脉曲张 #腿部健康 #运动 #clamav #外卖配送 #JADX-AI 插件 #语义检索 #向量嵌入 #boltbot #命令模式 #边缘AI # Kontron # SMARC-sAMX8 #starrocks #人脸活体检测 #live-pusher #动作引导 #张嘴眨眼摇头 #苹果ios安卓完美兼容 #L6 #L10 #L9 #OpenAI #故障 #软件需求 #个性化推荐 #BERT模型 #Qwen3-VL # 服务状态监控 # 视觉语言模型 #tekton #二值化 #Canny边缘检测 #轮廓检测 #透视变换 #因果学习 #新浪微博 #传媒 #隐函数 #常微分方程 #偏微分方程 #线性微分方程 #线性方程组 #非线性方程组 #复变函数 #DuckDB #协议 #Ward #思爱普 #SAP S/4HANA #ABAP #NetWeaver #4U8卡 AI 服务器 ##AI 服务器选型指南 #GPU 互联 #GPU算力 #Arduino BLDC #核辐射区域探测机器人 #esp32 #mosquito #效率神器 #办公技巧 #自动化工具 #Windows技巧 #打工人必备 #Python3.11 #Spire.Office #FRP #2025年 #AI教程 #0day漏洞 #DDoS攻击 #漏洞排查 #异步编程 #系统编程 #Pin #http服务器 # DIY主机 # 交叉编译 #自动化巡检 #istio #服务发现 #基金 #股票 #rag #AI赋能盾构隧道巡检 #开启基建安全新篇章 #以注意力为核心 #YOLOv12 #AI隧道盾构场景 #盾构管壁缺陷病害异常检测预警 #隧道病害缺陷检测 #ARMv8 #内存模型 #内存屏障 #娱乐 #敏捷流程 #AE #jquery #学术生涯规划 #CCF目录 #基金申请 #职称评定 #论文发表 #科研评价 #顶会顶刊