最新资讯

  • 【linux高性能服务器编程】项目实战——仿QQ聊天程序源码剖析

【linux高性能服务器编程】项目实战——仿QQ聊天程序源码剖析

2025-04-27 12:01:01 0 阅读

hello !大家好呀! 欢迎大家来到我的Linux高性能服务器编程系列之项目实战——仿QQ聊天程序源码剖析,在这篇文章中,你将会学习到如何利用Linux网络编程技术来实现一个简单的聊天程序,并且我会给出源码进行剖析,以及手绘UML图来帮助大家来理解,希望能让大家更能了解网络编程技术!!!

希望这篇文章能对你有所帮助,大家要是觉得我写的不错的话,那就点点免费的小爱心吧!(注:这章对于高性能服务器的架构非常重要哟!!!)

         

目录

一.项目介绍

二.服务器代码剖析

2.1 头文件和相关数据声明

2.2 服务器连接准备代码

2.3 服务器处理逻辑代码

2.3 客户端代码剖析


一.项目介绍

      像ssh这样的登录服务通常要同时处理网络连接和用户输入,这也可以使用I/O复用来实现。我们以poll为例实现一个简单的聊天室程序,以阐述如何使用I/O 复用技术来同时处理网络连接和用户输入。该聊天室程序能让所有用户同时在线群聊,它分为客户端和服务器两个部分。其中客户端程序有两个功能:一是从标准输入终端读入用户数据,并将用户数据发送至服务器;二是往标准输出终端打印服务器发送给它的数据。服务器的功能是接收,客户数据,并把客户数据发送给每一个登录到该服务器上的客户端(数据发送者除外)。下面我们依次给出客户端程序和服务器程序的代码。

二.服务器代码剖析

2.1 头文件和相关数据声明

#define _GNU_SOURCE 1
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define user_limit 5 //最大客户连接数量
#define buffer_size 64
#define fd_limit 65535 //最大文件描述符数量

struct client_data{//创建一个客户地址结构体
    struct sockaddr_in address ; 
    char * write_buf;
    char buf[buffer_size];
};
int setnonblocking (int fd){//将文件描述符改为非阻塞模式
    int old_option = fcntl(fd , F_GETFL);
    int new_option = old_option | O_NONBLOCK;// 添加非阻塞选项
    fcntl(fd , F_SETFL , new_option);//设置
    return old_option;

}

这部分代码包含了头文件,定义了一些宏,以及一个用于存储客户端数据的结构体,这个结构体是为了服务器更好控制来自客户端的socket套接字,以及灵活控制对socket套接字的读写,然后还定义了setnonblocking()函数来将传入的文件描述符利用fcntl函数改为非阻塞模式,方便服务器进行监听。

2.2 服务器连接准备代码

这段代码是服务器端程序的入口和初始化部分。下面是逐行的解释:

int main(int argc , char *argv[]){
    if(argc <= 2)//如果参数太少
    {
        printf("usage :%s ip_address port_number
",basename(argv[0]));
        return 1;
    }

这段代码检查命令行参数的数量。如果参数少于两个(程序名称和IP地址/端口号),则打印使用说明并退出程序。

    const char * ip = argv[1] ;// 提取ip地址
    int port = atoi(argv[2]); //提取端口号

从命令行参数中提取服务器的IP地址和端口号。

    struct sockaddr_in address ; //服务器地址
    bzero(&address ,sizeof(address));//清空
    address.sin_family = AF_INET;
    inet_pton(AF_INET , ip ,&address.sin_addr);//设置ip
    address.sin_port = htons(port); //设置端口号

这里创建了一个sockaddr_in结构体来存储服务器的地址信息,并使用bzero函数将其清零。然后设置地址族为AF_INET(IPv4),使用inet_pton函数将点分十进制的IP地址转换为网络字节序的格式,并存储在sin_addr字段中。最后,将端口号从主机字节序转换为网络字节序并存储在sin_port字段中。

    int listenfd = socket(PF_INET ,SOCK_STREAM , 0);//创建监听套接字
    assert(listenfd >=0);

创建一个TCP套接字(SOCK_STREAM)用于监听客户端连接,并检查套接字是否创建成功。

    int ret = bind(listenfd , (struct sockaddr*)&address , sizeof(address));//绑定
    assert(ret !=-1);

将套接字绑定到之前设置的服务器地址上,并检查绑定操作是否成功。

    ret = listen(listenfd ,5);//最多同时监听五个
    assert(ret!=-1);

调用listen函数,使套接字进入监听状态,并设置最大同时连接数为5。然后检查监听操作是否成功。

    //创建user数组,放入多个客户对象,并且使用socket的值可以直接用来索引(作为数组下标)连接对应的client_data对象
    struct client_data * user = malloc(fd_limit * sizeof(struct client_data));
   //为了提高poll性能,限制用户数量
    struct pollfd *fds = malloc(sizeof(struct pollfd) * 6);
    int user_counter = 0;//计算客户连接数量
    int i=0;
    for( i =  1 ; i<=user_limit ; ++i){//对每个fds数据初始化
        fds[i].fd = -1;
        fds[i].events =0;
    }

这段代码分配了两个数组:user数组用于存储客户端数据,fds数组用于poll函数。user数组的大小被设置为fd_limit,这是一个预定义的最大文件描述符数量。fds数组的大小被设置为6,这是因为服务器程序只监听一个套接字(listenfd),而其余的用于客户端连接。user_counter用于跟踪当前连接的客户端数量。fds数组的其余元素被初始化为-1,表示没有对应的文件描述符。

    //初始化怕poll中第一个数据:监听套接字
    fds[0].fd = listenfd;
    fds[0].events = POLLIN | POLLERR;
    fds[0].revents = 0;

最后,将监听套接字listenfd添加到fds数组中,并设置其监听的事件为可读事件(POLLIN)和错误事件(POLLERR)。revents字段用于poll函数返回时存储发生的事件,在这里初始化为0。

这段代码为服务器程序的后续操作设置了基础,包括套接字的创建和绑定,以及用于poll函数的数组的初始化。

2.3 服务器处理逻辑代码

这段代码是服务器程序的主循环,它使用poll系统调用来监控多个文件描述符(fds数组)的事件。这个循环会一直运行,直到遇到错误或者被显式地退出。

while(1){

这是一个无限循环,服务器程序将一直运行直到出现错误或者执行了退出循环的操作。

    ret = poll(fds , user_counter+1 , -1);//开始监听
    if(ret <0) {
        printf("poll failed..
");
        break;
    }

在循环的顶部,调用poll函数来等待事件发生。fds数组包含了所有需要监控的文件描述符,user_counter+1表示总共有user_counter个客户端连接加上监听套接字listenfd-1表示poll函数将阻塞直到至少有一个文件描述符上有事件发生。如果poll调用失败(返回值小于0),则打印错误信息并退出循环。

    for ( i =0 ; i =user_limit){//用户太多
                const char * info ="too many users
";
                printf("%s
",info);
                send(connfd , info ,strlen(info) , 0);//发送错误给客户端
                close(connfd);
                continue;
            }
            //对于新连接 ,我们要同时修改fds和users数组,user[connfd]即对应客户端数据
            user_counter++;//客户数量加一
            user[connfd].address = client_address;
            setnonblocking(connfd);//设置为非阻塞模式
            fds[user_counter].fd = connfd;//最新数据放入数组
            fds[user_counter].events = POLLIN | POLLRDHUP | POLLERR;
            fds[user_counter].revents = 0;
            printf("comes a new user , now have %d user
",user_counter);
        }
        // ... 其他事件处理逻辑 ...
    }

这个循环遍历fds数组中的每个文件描述符,检查它们是否有事件发生。对于每个事件,服务器程序执行相应的操作:

  1. 如果监听套接字(listenfd)上有新的连接请求(POLLIN事件),服务器接受新连接,并将新的文件描述符(connfd)添加到fds数组中。如果连接数超过限制(user_limit),服务器会发送一个错误消息并关闭新连接。

  2. 如果有任何文件描述符上有POLLERR事件,表示发生了错误,服务器会打印错误信息。

  3. 如果有任何已连接的套接字上有POLLIN事件,表示有数据可读,服务器会读取数据并打印。

  4. 如果有任何套接字上有POLLRDHUP事件,表示对方已经关闭了连接,服务器会关闭对应的连接并更新fds数组。

  5. 如果有任何套接字上有POLLOUT事件,表示可以写数据,服务器会发送数据(如果有数据要发送)。

在循环结束后,服务器程序会继续执行下一次循环,等待更多的连接和事件。

在服务器端代码中,poll函数用于监控多个文件描述符的事件。poll函数的返回值表示有多少个文件描述符发生了事件,而每个文件描述符的事件类型存储在revents字段中。下面是服务器端代码中使用poll函数监控的不同事件类型及其解释:

if(fds[i].fd==listenfd && (fds[i].revents & POLLIN)){
    // ... 接受连接逻辑 ...
}
else if(fds[i].revents & POLLERR){
    // ... 错误处理逻辑 ...
}
else if(fds[i].revents & POLLIN){
    // ... 读取数据逻辑 ...
}
else if(fds[i].revents & POLLRDHUP){
    // ... 关闭连接逻辑 ...
}
else if(fds[i].revents & POLLOUT){
    // ... 写数据逻辑 ...
}
  1. POLLIN: 这个事件表示文件描述符上有数据可读。对于服务器来说,这意味着有新的客户端连接请求或者已连接的客户端有数据发送过来。

  2. POLLERR: 这个事件表示文件描述符发生了错误。可能是网络错误,也可能是其他类型的错误。服务器需要检查并处理这些错误。

  3. POLLRDHUP: 这个事件表示文件描述符的读端已经被对方关闭。这通常发生在客户端突然断开连接的情况下。

  4. POLLOUT: 这个事件表示文件描述符的写端准备好了,可以写入数据。对于服务器来说,这意味着它可以向客户端发送数据。

服务器程序通过检查fds数组中每个文件描述符的revents字段,来确定发生了哪种事件,并相应地执行处理逻辑。如果没有任何事件发生,poll函数会阻塞,直到至少有一个文件描述符上有事件发生。服务器程序通过这种方式可以高效地处理多个客户端连接。

2.3 客户端代码剖析

这段代码是一个简单的客户端程序,用于连接到一个服务器,并通过标准输入和输出与服务器进行通信

#define _GNU_SOURCE 1
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include 
#include
#include
#define buffer_size 64 //缓冲区大小

这段代码包含了必要的头文件和宏定义。_GNU_SOURCE是一个宏,它用于启用一些GNU扩展,如splice系统调用。

int main(int argc , char * argv[])
{
    if(argc <= 2)//如果参数太少
    {
        printf("usage :%s ip_address port_number
",basename(argv[0]));
        return 1;
    }

这段代码检查命令行参数的数量。如果参数少于两个(程序名称和IP地址/端口号),则打印使用说明并退出程序。

    const char * ip = argv[1] ;// 提取ip地址
    int port = atoi(argv[2]); //提取端口号

从命令行参数中提取服务器的IP地址和端口号。

    struct sockaddr_in server_address ; //服务器地址
    bzero(&server_address ,sizeof(server_address));//清空
    server_address.sin_family = AF_INET;
    inet_pton(AF_INET , ip ,&server_address.sin_addr);//设置ip
    server_address.sin_port = htons(port); //设置端口号

创建一个sockaddr_in结构体来存储服务器的地址信息,并使用bzero函数将其清零。然后设置地址族为AF_INET(IPv4),使用inet_pton函数将点分十进制的IP地址转换为网络字节序的格式,并存储在sin_addr字段中。最后,将端口号从主机字节序转换为网络字节序并存储在sin_port字段中。

    int sockfd = socket(PF_INET , SOCK_STREAM , 0 );//创建本地套接字
    assert(socket >= 0 ); //判错
    if(connect(sockfd , (struct sockaddr *)&server_address , sizeof(server_address)) < 0){//连接失败的话
        printf("connection failed...
");
        close(sockfd);
        return 1;
    }

创建一个TCP套接字(SOCK_STREAM)用于与服务器通信,并检查套接字是否创建成功。然后尝试连接到服务器。如果连接失败,打印错误信息并退出程序。

    struct pollfd fds[2];//创建pollfd结构类型数组,注册标准输入和sockfd文件描述符上的可读事件
    fds[0].fd = 0;
    fds[0].events = POLLIN ;//标准输入可读
    fds[0].revents = 0; //实际发生事件,由内核填充
    fds[1].fd = sockfd;
    fds[1].events = POLLIN | POLLRDHUP ;//标准输入可读
    fds[1].revents = 0; //实际发生事件,由内核填充

创建一个pollfd结构体数组,用于监控标准输入(0)和套接字(sockfd)上的可读事件。

    while (1){
        ret = poll(fds , 2 , -1); //最大被监听事件只有两个, 返回符合条件文件总数
        if(ret < 0){//如果监听发生错误
            printf("poll falied..
");
            break;
        }

在循环的顶部,调用poll函数来等待事件发生。fds数组包含了所有需要监控的文件描述符,2表示总共有两个文件描述符(标准输入和套接字)。-1表示poll函数将阻塞直到至少有一个文件描述符上有事件发生。如果poll调用失败(返回值小于0),则打印错误信息并退出循环。

        if(fds[1].revents & POLLRDHUP){//假如发生了关闭对端连接
            printf("server close the connection..
");
            break;
        }
        else if(fds[1].revents & POLLIN){//假如sockfd文件发生可读,则读取服务器传来数据
            memset(readbuf , '' , buffer_size);
            recv(fds[1].fd , readbuf , buffer_size -1 , 0);//接收数据
             if(ret <= 0){// 如果接收失败或对方关闭了连接
                printf("server close the connection..
");
               break;
           }
            printf("%s
",readbuf);//打印数据
        }

 if(fds[0].revents & POLLIN){//标准输入文件描述符可读,说明我们需要写入数据

        ret = splice(0 , NULL , pipefd[1] , NULL ,32768 , SPLICE_F_MORE | SPLICE_F_MOVE);//从标准输入写入数据到管道写端
        ret = splice(pipefd[0] , NULL , sockfd , NULL ,32768 , SPLICE_F_MORE | SPLICE
        ret = splice(0 , NULL , pipefd[1] , NULL ,32768 , SPLICE_F_MORE | SPLICE_F_MOVE);//从标准输入写入数据到管道写端
        ret = splice(pipefd[0] , NULL , sockfd , NULL ,32768 , SPLICE_F_MORE | SPLICE_F_MOVE);//从管道读端将数据传输到sockfd
        printf("ok");
        }

    }
    close(sockfd);
    return 0;
}

这段代码检查套接字(sockfd)上的事件。如果套接字上有POLLRDHUP事件,表示对方已经关闭了连接,服务器会关闭对应的连接并退出循环。如果套接字上有POLLIN事件,表示有数据可读,服务器会读取数据并打印。

这段代码是客户端程序主循环的最后一部分,它处理标准输入(0)上的数据,并通过管道(pipefd)将其传输到套接字(sockfd)上。

  1. ret = splice(0 , NULL , pipefd[1] , NULL ,32768 , SPLICE_F_MORE | SPLICE_F_MOVE);:

    • splice是一个系统调用,用于直接在内核空间复制数据,避免了用户空间和内核空间之间的数据拷贝。
    • 第一个参数是源文件描述符,这里是从标准输入0
    • 第二个参数是源文件描述符的偏移量,这里为NULL,表示从文件开始读取。
    • 第三个参数是目标文件描述符,这里是对应的管道写端pipefd[1]
    • 第四个参数是目标文件描述符的偏移量,这里为NULL,表示从文件开始写入。
    • 第五个参数是传输的数据量,这里为32768,是一个系统定义的常量,表示最多传输32768字节。
    • 第六个参数是SPLICE_F_MORE,表示这只是一个中间步骤,还有更多的数据要传输。
    • 第七个参数是SPLICE_F_MOVE,表示传输的数据是从内核缓冲区直接移动,而不是复制。
  2. ret = splice(pipefd[0] , NULL , sockfd , NULL ,32768 , SPLICE_F_MORE | SPLICE_F_MOVE);:

    • 类似地,这段代码使用splice系统调用来从管道读端pipefd[0]传输数据到套接字sockfd
  3. printf("ok");:

    • 打印"ok"表示数据传输成功。

循环继续执行,重复上述操作,直到连接被关闭或出现错误。

  1. close(sockfd);:

    • 关闭套接字sockfd,释放资源。
  2. return 0;:

    • 程序返回0,表示正常退出。

这个客户端程序通过poll系统调用来监控标准输入和套接字的事件,并通过splice系统调用来高效地传输数据。它使用管道作为中间缓冲区,以避免在用户空间和内核空间之间进行数据拷贝。

   好啦!到这里这篇文章就结束啦,关于实例代码中我写了很多注释,如果大家还有不懂得,可以评论区或者私信我都可以哦!! 感谢大家的阅读,我还会持续创造网络编程相关内容的,记得点点小爱心和关注哟! 

本文地址:https://www.vps345.com/3319.html

搜索文章

Tags

PV计算 带宽计算 流量带宽 服务器带宽 上行带宽 上行速率 什么是上行带宽? CC攻击 攻击怎么办 流量攻击 DDOS攻击 服务器被攻击怎么办 源IP 服务器 linux 运维 游戏 云计算 javascript 前端 chrome edge 进程 操作系统 进程控制 Ubuntu python MCP 阿里云 网络 网络安全 网络协议 llama 算法 opencv 自然语言处理 神经网络 语言模型 ssh ubuntu deepseek Ollama 模型联网 API CherryStudio 科技 ai java 人工智能 个人开发 harmonyos 华为 开发语言 typescript 计算机网络 数据库 centos oracle 关系型 安全 分布式 RTSP xop RTP RTSPServer 推流 视频 udp unity YOLO efficientVIT YOLOv8替换主干网络 TOLOv8 面试 性能优化 jdk intellij-idea 架构 php android 宝塔面板访问不了 宝塔面板网站访问不了 宝塔面板怎么配置网站能访问 宝塔面板配置ip访问 宝塔面板配置域名访问教程 宝塔面板配置教程 Dell R750XS vue.js audio vue音乐播放器 vue播放音频文件 Audio音频播放器自定义样式 播放暂停进度条音量调节快进快退 自定义audio覆盖默认样式 rust http 学习 uni-app 深度学习 目标检测 计算机视觉 fastapi mcp mcp-proxy mcp-inspector fastapi-mcp agent sse filezilla 无法连接服务器 连接被服务器拒绝 vsftpd 331/530 HCIE 数通 pycharm ide pytorch GaN HEMT 氮化镓 单粒子烧毁 辐射损伤 辐照效应 ssl 前端框架 macos adb numpy asm c# Flask FastAPI Waitress Gunicorn uWSGI Uvicorn flutter Hyper-V WinRM TrustedHosts tcp/ip 鸿蒙 github debian PVE AI编程 物联网 iot 华为云 rabbitmq golang 后端 websocket Qwen2.5-coder 离线部署 windows ollama 大模型 mac c++ react.js 前端面试题 node.js 持续部署 Dify pip conda 机器学习 redis mybatis oceanbase rc.local 开机自启 systemd 麒麟 llm transformer chatgpt llama3 Chatglm 开源大模型 WSL2 gpu算力 ping++ 运维开发 深度优先 图论 并集查找 换根法 树上倍增 ddos 笔记 开源 docker 容器 ffmpeg 音视频 学习方法 zotero WebDAV 同步失败 代理模式 嵌入式硬件 单片机 温湿度数据上传到服务器 Arduino HTTP 银河麒麟服务器操作系统 系统激活 fpga开发 博客 安装教程 GPU环境配置 Ubuntu22 CUDA PyTorch Anaconda安装 sql KingBase 负载均衡 计算机外设 电脑 软件需求 ESP32 智能手机 NAS Termux Samba Linux flask spring boot AIGC tomcat postman mock mock server 模拟服务器 mock服务器 Postman内置变量 Postman随机数据 LDAP mysql jenkins gitee aws googlecloud 实时音视频 Windsurf vscode 微信 微信分享 Image wxopensdk 腾讯云 maven intellij idea git ansible nginx dubbo .netcore word图片自动上传 word一键转存 复制word图片 复制word图文 复制word公式 粘贴word图文 粘贴word公式 大数据 爬虫 数据挖掘 网络用户购物行为分析可视化平台 大数据毕业设计 1024程序员节 kamailio sip VoIP 大数据平台 .net 数据结构 c语言 经验分享 sqlserver rust腐蚀 豆瓣 追剧助手 迅雷 nas HarmonyOS Next vim 低代码 gitlab 命名管道 客户端与服务端通信 mcu 信息与通信 YOLOv12 jmeter 软件测试 gateway Clion Nova ResharperC++引擎 Centos7 远程开发 多线程服务器 Linux网络编程 监控 自动化运维 firewalld 智能路由器 外网访问 内网穿透 端口映射 AI Agent pillow live555 rtsp rtp json html5 firefox 产品经理 agi microsoft mongodb WSL win11 无法解析服务器的名称或地址 https C 环境变量 进程地址空间 web安全 Kali Linux 黑客 渗透测试 信息收集 django web3.py cuda cudnn anaconda 小程序 微信小程序域名配置 微信小程序服务器域名 微信小程序合法域名 小程序配置业务域名 微信小程序需要域名吗 微信小程序添加域名 微服务 springcloud kubernetes 程序人生 嵌入式 linux驱动开发 arm开发 vue3 HTML audio 控件组件 vue3 audio音乐播放器 Audio标签自定义样式默认 vue3播放音频文件音效音乐 自定义audio播放器样式 播放暂停调整声音大小下载文件 僵尸进程 进程信号 代码调试 ipdb VMware安装Ubuntu Ubuntu安装k8s k8s ollama下载加速 创意 社区 DeepSeek-R1 API接口 源码剖析 rtsp实现步骤 流媒体开发 cpu 内存 实时 使用 远程控制 远程看看 远程协助 C语言 YOLOv8 NPU Atlas800 A300I pro asi_bench 自动化 蓝耘科技 元生代平台工作流 ComfyUI Ubuntu Server Ubuntu 22.04.5 DigitalOcean GPU服务器购买 GPU服务器哪里有 GPU服务器 apache 统信UOS bonding 链路聚合 camera Arduino 电子信息 mount挂载磁盘 wrong fs type LVM挂载磁盘 Centos7.9 qt stm32项目 stm32 unix 大语言模型 prometheus 能力提升 面试宝典 技术 IT信息化 iDRAC R720xd make命令 makefile文件 selenium 测试工具 DeepSeek 服务器繁忙 ESXi ip命令 新增网卡 新增IP 启动网卡 playbook iftop 网络流量监控 thingsboard postgresql 鸿蒙系统 XFS xfs文件系统损坏 I_O error Docker Hub docker pull 镜像源 daemon.json es jvm netty 安卓 svn shell 磁盘监控 NFS 监控k8s 监控kubernetes jupyter dell服务器 go DevEco Studio 硬件架构 系统架构 webrtc elasticsearch IIS .net core Hosting Bundle .NET Framework vs2022 WebUI DeepSeek V3 AI大模型 状态管理的 UDP 服务器 Arduino RTOS html zabbix file server http server web server 驱动开发 数据集 集成学习 集成测试 文件系统 路径解析 yum LLM 大模型面经 职场和发展 Deepseek 大模型学习 缓存 服务器配置 生物信息学 openEuler threejs 3D gitea 王者荣耀 远程工作 DNS minio Invalid Host allowedHosts vue MacOS录屏软件 远程连接 rdp 实验 计算机 mamba Vmamba SysBench 基准测试 交换机 硬件 设备 GPU PCI-Express 微信小程序 编辑器 kylin jetty undertow express UOS 统信操作系统 spring 并查集 leetcode 云电竞 云电脑 todesk RAGFLOW RAG 检索增强生成 文档解析 大模型垂直应用 Erlang OTP gen_server 热代码交换 事务语义 gpt linux上传下载 MNN Qwen 医疗APP开发 app开发 ip bash ui 游戏服务器 Minecraft 云原生 音乐服务器 Navidrome 音流 监控k8s集群 集群内prometheus Playwright 自动化测试 Cline 自动化编程 DeepSeek行业应用 Heroku 网站部署 kafka 系统安全 freebsd MQTT协议 消息服务器 代码 hugo k8s集群资源管理 云原生开发 hadoop 媒体 部署 Dell HPE 联想 浪潮 远程桌面 docker run 数据卷挂载 交互模式 vmware 卡死 list java-ee Ubuntu 24 常用命令 Ubuntu 24 Ubuntu vi 异常处理 压力测试 测试用例 功能测试 eureka ruoyi Trae AI代码编辑器 kind AI写作 AI作画 react next.js 部署next.js QQ 聊天室 spring cloud kali 共享文件夹 虚拟机 ai小智 语音助手 ai小智配网 ai小智教程 智能硬件 esp32语音助手 diy语音助手 技能大赛 命令 asp.net大文件上传 asp.net大文件上传源码 ASP.NET断点续传 asp.net上传文件夹 asp.net上传大文件 .net core断点续传 .net mvc断点续传 思科模拟器 思科 Cisco ros2 moveit 机器人运动 linux环境变量 telnet 远程登录 muduo X11 Xming 其他 okhttp 剧本 eNSP 网络规划 VLAN 企业网络 wireshark 显示过滤器 安装 ICMP Wireshark安装 pygame ci/cd devops Linux awk awk函数 awk结构 awk内置变量 awk参数 awk脚本 awk详解 k8s资源监控 annotations自动化 自动化监控 监控service 监控jvm 高效远程协作 TrustViewer体验 跨设备操作便利 智能远程控制 灵办AI kvm 弹性计算 虚拟化 KVM 计算虚拟化 弹性裸金属 工业4.0 rime 机器人 游戏程序 windwos防火墙 defender防火墙 win防火墙白名单 防火墙白名单效果 防火墙只允许指定应用上网 防火墙允许指定上网其它禁止 漏洞 Docker Compose docker compose docker-compose 微信开放平台 微信公众平台 微信公众号配置 安全威胁分析 vscode 1.86 Linux无人智慧超市 LInux多线程服务器 QT项目 LInux项目 单片机项目 grafana 图形化界面 visual studio code 直流充电桩 充电桩 IPMI 网站搭建 serv00 云服务器 裸金属服务器 弹性裸金属服务器 p2p GCC crosstool-ng unity3d 银河麒麟 kylin v10 麒麟 v10 SSH Xterminal wsl2 wsl TRAE SWAT 配置文件 服务管理 网络共享 华为od 多层架构 解耦 dify Netty 即时通信 NIO 分析解读 边缘计算 micropython esp32 mqtt 实时互动 ceph IIS服务器 IIS性能 日志监控 selete 高级IO 程序员 virtualenv rpc nuxt3 半虚拟化 硬件虚拟化 Hypervisor 政务 分布式系统 监控运维 Prometheus Grafana matlab 田俊楠 深度求索 私域 知识库 sqlite MS Materials tcpdump openssl 密码学 gpt-3 文心一言 业界资讯 设计模式 软件工程 模拟退火算法 rocketmq code-server MQTT mosquitto 消息队列 r语言 数据可视化 数据分析 中间件 可信计算技术 安全架构 网络攻击模型 pgpool echarts 信息可视化 网页设计 腾讯云大模型知识引擎 小艺 Pura X 数据库系统 excel hibernate jar gradle 课程设计 etcd 数据安全 RBAC protobuf 序列化和反序列化 企业微信 Linux24.04 deepin C# MQTTS 双向认证 emqx MacMini Mac 迷你主机 mini Apple 金融 webstorm 宠物 毕业设计 免费学习 宠物领养 宠物平台 统信 国产操作系统 虚拟机安装 框架搭建 强制清理 强制删除 mac废纸篓 报错 宝塔面板 同步 备份 建站 W5500 OLED u8g2 TCP服务器 Java chfs ubuntu 16.04 大模型入门 大模型教程 remote-ssh ios ukui 麒麟kylinos openeuler 网络穿透 VR手套 数据手套 动捕手套 动捕数据手套 JAVA Ark-TS语言 bug iBMC UltraISO 火绒安全 VPS Nuxt.js docker搭建nacos详解 docker部署nacos docker安装nacos 腾讯云搭建nacos centos7搭建nacos springboot远程调试 java项目远程debug docker远程debug java项目远程调试 springboot远程 vSphere vCenter 软件定义数据中心 sddc 3d 数学建模 RTMP 应用层 RAID RAID技术 磁盘 存储 CORS 跨域 雨云 NPS 孤岛惊魂4 uniapp cmos 输入法 OD机试真题 华为OD机试真题 服务器能耗统计 恒源云 av1 电视盒子 机顶盒ROM 魔百盒刷机 arm 传统数据库升级 银行 LLMs 远程 执行 sshpass 操作 多进程 IPMITOOL BMC 硬件管理 opcua opcda KEPServer安装 oneapi VMware安装mocOS VMware macOS系统安装 大模型微调 open webui 服务器数据恢复 数据恢复 存储数据恢复 北亚数据恢复 oracle数据恢复 gcc dba ArcTS 登录 ArcUI GridItem arkUI ecmascript pdf VSCode 华为认证 网络工程师 移动云 android studio n8n 工作流 workflow 鲲鹏 FTP 服务器 XCC Lenovo chrome devtools chromedriver 繁忙 解决办法 替代网站 汇总推荐 AI推理 Cookie embedding SSL 域名 raid5数据恢复 磁盘阵列数据恢复 skynet 系统开发 binder 车载系统 framework 源码环境 visualstudio Cursor mariadb Portainer搭建 Portainer使用 Portainer使用详解 Portainer详解 Portainer portainer 硬件工程 嵌入式实习 ue4 着色器 ue5 虚幻 目标跟踪 OpenVINO 推理应用 开机自启动 Linux PID IDE AI 原生集成开发环境 Trae AI EasyConnect 小游戏 五子棋 nextjs reactjs RustDesk自建服务器 rustdesk服务器 docker rustdesk sdkman 黑客技术 流式接口 URL 本地部署 api web pyqt bot Docker Kylin-Server 服务器安装 Reactor C++ ux 多线程 Google pay Apple pay nvidia 服务器主板 AI芯片 open Euler dde 交互 网工 opensearch helm 搜索引擎 ssrf 失效的访问控制 WebRTC openwrt 源码 英语 adobe elk 混合开发 环境安装 JDK Python 网络编程 聊天服务器 套接字 TCP 客户端 Socket CLion xrdp 蓝桥杯 string模拟实现 深拷贝 浅拷贝 经典的string类问题 三个swap TrinityCore 魔兽世界 mysql离线安装 ubuntu22.04 mysql8.0 图像处理 Ubuntu 24.04.1 轻量级服务器 hive Hive环境搭建 hive3环境 Hive远程模式 redhat 服务器管理 配置教程 网站管理 群晖 文件分享 curl wget iis centos-root /dev/mapper yum clean all df -h / du -sh 雨云服务器 springsecurity6 oauth2 授权服务器 token sas 京东云 环境迁移 崖山数据库 YashanDB 命令行 基础入门 编程 Redis Desktop 直播推流 服务器部署ai模型 linux 命令 sed 命令 rsyslog RoboVLM 通用机器人策略 VLA设计哲学 vlm fot robot 视觉语言动作模型 具身智能 毕设 相差8小时 UTC 时间 springboot sqlite3 设置代理 实用教程 Anolis nginx安装 linux插件下载 flash-attention 银河麒麟操作系统 国产化 远程过程调用 Windows环境 Ubuntu DeepSeek DeepSeek Ubuntu DeepSeek 本地部署 DeepSeek 知识库 DeepSeek 私有化知识库 本地部署 DeepSeek DeepSeek 私有化部署 SSH 服务 SSH Server OpenSSH Server ragflow ipython 串口服务器 向日葵 无桌面 risc-v bootstrap minicom 串口调试工具 matplotlib 飞牛NAS 飞牛OS MacBook Pro cnn css 联想开天P90Z装win10 safari 系统 ecm bpm 压测 ECS CPU 主板 电源 网卡 宕机切换 服务器宕机 5G 3GPP 卫星通信 指令 mq 数据库架构 数据管理 数据治理 数据编织 数据虚拟化 idm docker命令大全 Linux的权限 c/c++ 串口 怎么卸载MySQL MySQL怎么卸载干净 MySQL卸载重新安装教程 MySQL5.7卸载 Linux卸载MySQL8.0 如何卸载MySQL教程 MySQL卸载与安装 H3C 安防软件 端口测试 李心怡 常用命令 文本命令 目录命令 iphone python3.11 性能测试 音乐库 飞牛 影刀 #影刀RPA# 用户缓冲区 sentinel 模拟实现 前后端分离 支付 微信支付 开放平台 midjourney 服务器无法访问 ip地址无法访问 无法访问宝塔面板 宝塔面板打不开 fd 文件描述符 FunASR ASR 佛山戴尔服务器维修 佛山三水服务器维修 Claude npm Jellyfin c cocoapods xcode AnythingLLM AnythingLLM安装 无人机 ROS 自动驾驶 TrueLicense SenseVoice 流水线 脚本式流水线 Wi-Fi 版本 Spring Security 我的世界 我的世界联机 数码 DenseNet yolov8 CrewAI 信号处理 Kali 渗透 超融合 干货分享 黑客工具 密码爆破 figma qemu libvirt 技术共享 我的世界服务器搭建 WebVM 基础环境 昇腾 npu can 线程池 GoogLeNet WSL2 上安装 Ubuntu eclipse CH340 串口驱动 CH341 uart 485 服务器时间 vpn ISO镜像作为本地源 执法记录仪 智能安全帽 smarteye Ubuntu22.04 开发人员主页 trea idea ArkTs ArkUI 备份SQL Server数据库 数据库备份 傲梅企业备份网络版 网络药理学 生信 gromacs 分子动力学模拟 MD 动力学模拟 USB网络共享 bcompare Beyond Compare 模拟器 教程 dns是什么 如何设置电脑dns dns应该如何设置 xss 在线预览 xlsx xls文件 在浏览器直接打开解析xls表格 前端实现vue3打开excel 文件地址url或接口文档流二进 ssh漏洞 ssh9.9p2 CVE-2025-23419 pppoe radius ocr gaussdb Mac内存不够用怎么办 linux安装配置 IM即时通讯 剪切板对通 HTML FORMAT RAGFlow 本地知识库部署 DeepSeek R1 模型 etl saltstack lsb_release /etc/issue /proc/version uname -r 查看ubuntu版本 键盘 嵌入式Linux IPC AI agent EMUI 回退 降级 升级 云服务 apt 算力 中兴光猫 换光猫 网络桥接 自己换光猫 uni-file-picker 拍摄从相册选择 uni.uploadFile H5上传图片 微信小程序上传图片 个人博客 矩阵 powerpoint 阿里云ECS dity make 社交电子 反向代理 实战案例 EMQX 通信协议 VS Code 链表 searxng 单元测试 Docker引擎已经停止 Docker无法使用 WSL进度一直是0 镜像加速地址 perf edge浏览器 DBeaver 数据仓库 kerberos less cfssl 显示管理器 lightdm gdm composer 游戏开发 阻塞队列 生产者消费者模型 服务器崩坏原因 产测工具框架 IMX6ULL 管理框架 小番茄C盘清理 便捷易用C盘清理工具 小番茄C盘清理的优势尽显何处? 教你深度体验小番茄C盘清理 C盘变红?!不知所措? C盘瘦身后电脑会发生什么变化? laravel langchain 小智AI服务端 xiaozhi TTS 换源 国内源 Debian firewall junit openstack Xen 远程服务 AD 域管理 trae Typore nac 802.1 portal x64 SIGSEGV SSE xmm0 稳定性 看门狗 磁盘镜像 服务器镜像 服务器实时复制 实时文件备份 Logstash 日志采集 tensorflow 备选 网站 调用 示例 银河麒麟桌面操作系统 Kylin OS 程序 性能分析 AD域 游戏机 毕昇JDK tcp HTTP 服务器控制 ESP32 DeepSeek 聚类 minecraft 网络结构图 yaml Ultralytics 可视化 交叉编译 vasp安装 查询数据库服务IP地址 SQL Server 语音识别 AutoDL 虚拟局域网 Linux环境 分布式训练 强化学习 prompt 大模型应用 Radius OpenSSH qt项目 qt项目实战 qt教程 wordpress 无法访问wordpess后台 打开网站页面错乱 linux宝塔面板 wordpress更换服务器 EtherNet/IP串口网关 EIP转RS485 EIP转Modbus EtherNet/IP网关协议 EIP转RS485网关 EIP串口服务器 国标28181 视频监控 监控接入 语音广播 流程 SIP SDP 信号 显卡驱动 根服务器 华为机试 序列化反序列化 AISphereButler clickhouse IPv4 子网掩码 公网IP 私有IP 匿名管道 SSH 密钥生成 SSH 公钥 私钥 生成 主从复制 outlook frp 人工智能生成内容 银河麒麟高级服务器 外接硬盘 Kylin Linux的基础指令 线程 seleium 单例模式 做raid 装系统 Java Applet URL操作 服务器建立 Socket编程 网络文件读取 Ubuntu共享文件夹 共享目录 Linux共享文件夹 ruby 游戏引擎 xml EtherCAT转Modbus ECT转Modbus协议 EtherCAT转485网关 ECT转Modbus串口网关 EtherCAT转485协议 ECT转Modbus网关 P2P HDLC CVE-2024-7347 rustdesk 双系统 GRUB引导 Linux技巧 内网服务器 内网代理 内网通信 VM搭建win2012 win2012应急响应靶机搭建 攻击者获取服务器权限 上传wakaung病毒 应急响应并溯源 挖矿病毒处置 应急响应综合性靶场 程序员创富 需求分析 规格说明书 dns lio-sam SLAM uv big data glibc 飞书 虚拟显示器 7z 致远OA OA服务器 服务器磁盘扩容 web3 keepalived ros sonoma 自动更新 单一职责原则 重启 排查 系统重启 日志 原因 IO模型 xshell termius iterm2 软负载 AI-native Docker Desktop neo4j 数据库开发 database wps ubuntu24.04.1 服务网格 istio asp.net大文件上传下载 读写锁 办公自动化 自动化生成 pdf教程 spark HistoryServer Spark YARN jobhistory CDN Headless Linux rnn seatunnel nfs g++ g++13 AP配网 AK配网 小程序AP配网和AK配网教程 WIFI设备配网小程序UDP开 flink arcgis 自定义客户端 SAS 僵尸世界大战 游戏服务器搭建 zookeeper LInux 软件构建 LORA NLP IMX317 MIPI H265 VCU 大大通 第三代半导体 碳化硅 pyautogui 回显服务器 UDP的API使用 Windows ai工具 v10 软件 ldap armbian u-boot rag ragflow 源码启动 语法 运维监控 k8s二次开发 集群管理 本地部署AI大模型 GIS 遥感 WebGIS 黑苹果 banner h.264 代理 项目部署到linux服务器 项目部署过程 ftp 捆绑 链接 谷歌浏览器 youtube google gmail 图形渲染 宝塔 vscode1.86 1.86版本 ssh远程连接 LLM Web APP Streamlit DeepSeek r1 Open WebUI cpp-httplib cd 目录切换 迁移指南 OpenManus MI300x alias unalias 别名 sysctl.conf vm.nr_hugepages NLP模型 策略模式 自学笔记 小米 澎湃OS Android regedit 开机启动 miniapp 真机调试 调试 debug 断点 网络API请求调试方法 Node-Red 编程工具 流编程 SRS 流媒体 直播 开发环境 SSL证书 dash 正则表达式 视觉检测 webgl bat VMware创建虚拟机 HarmonyOS odoo 服务器动作 Server action 考研 tidb GLIBC 视频编解码 私有化 代码托管服务 高效日志打印 串口通信日志 服务器日志 系统状态监控日志 异常记录日志 deep learning UOS1070e 实习 rclone AList webdav fnOS DIFY 相机 权限 swoole epoll 三级等保 服务器审计日志备份 FTP服务器 自动化任务管理 easyui 移动魔百盒 推荐算法 架构与原理 USB转串口 飞牛nas fnos 软考 邮件APP 免费软件 log4j yum源切换 更换国内yum源 多个客户端访问 IO多路复用 TCP相关API 互信 vr 上传视频至服务器代码 vue3批量上传多个视频并预览 如何实现将本地视频上传到网页 element plu视频上传 ant design vue vue3本地上传视频及预览移除 tailscale derp derper 中转 历史版本 下载 triton 模型分析 线性代数 电商平台 大文件分片上传断点续传及进度条 如何批量上传超大文件并显示进度 axios大文件切片上传详细教 node服务器合并切片 vue3大文件上传报错提示错误 大文件秒传跨域报错cors IDEA C++软件实战问题排查经验分享 0xfeeefeee 0xcdcdcdcd 动态库加载失败 程序启动失败 程序运行权限 标准用户权限与管理员权限 Unity Dedicated Server Host Client 无头主机 lua vue-i18n 国际化多语言 vue2中英文切换详细教程 如何动态加载i18n语言包 把语言json放到服务器调用 前端调用api获取语言配置文件 DocFlow cursor MCP server C/S aarch64 编译安装 HPC windows日志 Deepseek-R1 私有化部署 推理模型 免费域名 域名解析 deepseek r1 DOIT 四博智联 树莓派 VNC 粘包问题 perl 域名服务 DHCP 符号链接 配置 docker部署Python 镜像 Unity插件 PX4 Python基础 Python教程 Python技巧 iventoy VmWare OpenEuler css3 浏览器自动化 navicat 云桌面 微软 AD域控 证书服务器 zip unzip 软链接 硬链接 Linux权限 权限命令 特殊权限 加解密 Yakit yaklang Attention UDP 网络爬虫 word kernel 流量运营 带外管理 增强现实 沉浸式体验 应用场景 技术实现 案例分析 AR 多路转接 虚幻引擎 virtualbox vu大文件秒传跨域报错cors 大模型推理 问题解决 ubuntu24 vivado24 MacOS kotlin ssh远程登录 浏览器开发 AI浏览器 进程优先级 调度队列 进程切换 llama.cpp Sealos 论文阅读 rancher 烟花代码 烟花 元旦 性能调优 安全代理 嵌入式系统开发 WLAN gnu 代理服务器 状态模式 多端开发 智慧分发 应用生态 鸿蒙OS 环境配置 网络建设与运维 网络搭建 神州数码 神州数码云平台 云平台 rtsp服务器 rtsp server android rtsp服务 安卓rtsp服务器 移动端rtsp服务 大牛直播SDK su sudo ip协议 PPI String Cytoscape CytoHubba 云耀服务器 grub 版本升级 扩容 TCP协议 抗锯齿 拓扑图 hexo 元服务 应用上架 上传视频文件到服务器 uniApp本地上传视频并预览 uniapp移动端h5网页 uniapp微信小程序上传视频 uniapp app端视频上传 uniapp uview组件库 知识图谱 deekseek SEO nlp milvus 健康医疗 互联网医院 大模型部署 查看显卡进程 fuser ArtTS MVS 海康威视相机 proxy模式 信创 信创终端 中科方德 极限编程 CentOS onlyoffice 在线office 磁盘清理 SVN Server tortoise svn fast ABAP 容器技术 jina HAProxy 物联网开发 存储维护 NetApp存储 EMC存储 ShenTong docker搭建pg docker搭建pgsql pg授权 postgresql使用 postgresql搭建 iperf3 带宽测试 虚拟现实 对比 工具 meld DiffMerge 开发 QT 5.12.12 QT开发环境 Ubuntu18.04 hosts nvm whistle autodl 项目部署 AI员工 IMM 智能音箱 智能家居 wpf HarmonyOS NEXT 原生鸿蒙 deployment daemonset statefulset cronjob AI Agent 字节智能运维 合成模型 扩散模型 图像生成 MDK 嵌入式开发工具 论文笔记 sublime text fstab wsgiref Web 服务器网关接口 Qwen2.5-VL vllm OpenHarmony ardunio BLE 鸿蒙开发 移动开发 java-rocketmq nosql 沙盒 内网环境 react native sequoiaDB 端口聚合 windows11 Linux find grep 钉钉 prometheus数据采集 prometheus数据模型 prometheus特点 CentOS Stream 网卡的名称修改 eth0 ens33 win服务器架设 windows server 计算生物学 生物信息 基因组 System V共享内存 进程通信 HiCar CarLife+ CarPlay QT RK3588 docker desktop image top Linux top top命令详解 top命令重点 top常用参数 xpath定位元素 本地化部署 db 端口 查看 ss ubuntu20.04 ros1 Noetic 20.04 apt 安装 chrome 浏览器下载 chrome 下载安装 谷歌浏览器下载 玩机技巧 软件分享 软件图标 区块链 docker部署翻译组件 docker部署deepl docker搭建deepl java对接deepl 翻译组件使用 企业网络规划 华为eNSP rpa MySql harmonyOS面试题 visual studio 软件卸载 系统清理 Xinference ranger MySQL8.0 KylinV10 麒麟操作系统 Vmware 金仓数据库 2025 征文 数据库平替用金仓 抓包工具 欧标 OCPP 防火墙 NAT转发 NAT Server mcp服务器 client close vnc yum换源 开机黑屏 电视剧收视率分析与可视化平台 西门子PLC 通讯 centos 7 MAVROS 四旋翼无人机 React Next.js 开源框架 conda配置 conda镜像源 ubuntu 18.04 安装MySQL 通信工程 毕业 数字证书 签署证书 openvpn server openvpn配置教程 centos安装openvpn dock 加速 风扇控制软件 智能电视 mm-wiki搭建 linux搭建mm-wiki mm-wiki搭建与使用 mm-wiki使用 mm-wiki详解 热榜 服务器正确解析请求体 IO macOS js 达梦 DM8 MobaXterm 接口优化 搜狗输入法 中文输入法 搭建个人相关服务器 离线部署dify yolov5 解决方案 像素流送api 像素流送UE4 像素流送卡顿 像素流送并发支持