• linux网络编程4——WebSocket协议及服务器的简易实现

linux网络编程4——WebSocket协议及服务器的简易实现

2025-05-04 20:00:08 0 阅读

文章目录

    • 1. WebSocket服务器介绍
        • 1.1 WebSocket 协议的特点
        • 1.2 WebSocket 与 HTTP 的区别:
        • 1.3 WebSocket 的应用场景:
    • 2. WebSocket握手协议详解
    • 3. 可能出现的错误
    • 4. 握手协议编码实现
    • 5. websocket传输协议实现
        • 5.1 websocket帧格式
        • 5.2 解包客户端数据
        • 5.3 服务端发包
    • 学习参考

1. WebSocket服务器介绍

本文详细介绍了WebSocket协议的特点、与HTTP的区别以及应用场景;然后分析了WebSocket协议的主要内容;最后借助前面的底层reactor的代码实现了一个WebSocket协议的Web服务器。

完整项目代码参考:我的github项目

WebSocket 是一种在客户端(通常是浏览器)和服务器之间建立双向通信通道的协议,允许它们通过一个持久的 TCP 连接进行实时数据交换。与传统的 HTTP 请求-响应模型不同,WebSocket 提供了全双工(full-duplex)的通信,即客户端和服务器都可以在任何时间向对方发送消息,而无需等待响应。

1.1 WebSocket 协议的特点
  1. 持久连接:WebSocket 建立连接后,它保持打开状态,客户端和服务器之间可以持续交换数据,直到连接被一方主动关闭。
  2. 全双工通信:双向通信通道可以同时发送和接收数据。服务器可以在不依赖客户端请求的情况下推送数据。
  3. 减少网络开销:WebSocket 通过升级一次 HTTP 请求来建立连接,之后的数据交换只通过轻量的 WebSocket 帧格式,而不像 HTTP 需要额外的请求头部信息,因而大大减少了网络开销。
  4. 实时数据传输:适合实时应用,如在线聊天、股票行情、游戏、物联网数据传输等。

WebSocket协议是通过HTTP1.1协议的握手过程建立的,但连接建立后两者的通信机制完全不同。

WebSocket握手头部

GET /chat HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13

WebSocket握手成功后升级连接

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
1.2 WebSocket 与 HTTP 的区别:
  • 双向通信 vs 单向请求响应:HTTP 是单向的请求-响应模型,客户端必须发起请求,服务器响应。而 WebSocket 是双向的,双方可以随时发送数据。
  • 持久连接:HTTP 需要每次发起新的连接请求(即使是 HTTP/1.1,也需要保持连接),而 WebSocket 在建立连接后,连接是持久的,直到主动关闭。
  • 协议头部大小:HTTP 请求和响应头部信息较多,而 WebSocket 帧的协议头部相对较少,减少了数据传输的开销。
1.3 WebSocket 的应用场景:

Http协议和WebSocket协议常常结合使用,例如HTTP用于初始的页面加载和静态资源获取,WebSocket用于需要长时间实时交互的场景。

  1. 实时聊天:像 Slack、微信、Facebook Messenger 这样需要实时通信的应用。
  2. 实时股票行情:股票交易平台、加密货币交易所等,需要不断推送最新的市场数据。
  3. 多人在线游戏:游戏服务器需要与每个客户端频繁、实时交换数据。
  4. 实时通知系统:例如社交网络中的通知,或电子商务中的订单更新。
  5. IoT 设备管理:物联网应用可以使用 WebSocket 实时管理和监控设备的状态。

2. WebSocket握手协议详解

主要介绍握手协议,在握手阶段,客户端会在请求头中发送一个sec-websocket-key

sec-websocket-key: e3bLzpFK7Li8RHh8DZL87A==

服务器需要拿到这个key值,然后进行如下计算

  • 将key与一个GUID连结,该GUID值为258EAFA5-E914-47DA-95CA-C5AB0DC85B11,得到input
  • 使用SHA-1算法计算input得到input2
  • 使用base64算法计算input2得到ouput

最后在响应头中发送sec-websocket-Accpet头即可

Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

之后,双方可以保持连接,进行实时的全双工的交互。

3. 可能出现的错误

  1. 编译时链接器显示找不到一些符号的定义

    记得链接ssl库和crypto库

    gcc -o xxx xxx1.c xxx2.c -lssl -lcrypto
    
  2. 客户端发送”unknown opcode",并主动关闭连接

​ 一定是服务端发送的数据不符合协议,或者Sec-WebSocket-Accept值有误。

4. 握手协议编码实现

这里只实现了建立握手协议这一环节,连接建立后发送的消息都应该遵守websocket协议的格式。完整的websocket回声服务器代码可参考完整项目代码参考:我的github项目。

完整的websocket协议请参考rfc6455。

#include 

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include "webserver.h"
#include "websocket.h"

#define DEBUG

#define WEBSOCKET_KEY_LENGTH 256

// 负责按照rfc6455的规定输出Sec-WebSocket-Accept的值
static int encode_key(unsigned char *key, size_t n, unsigned char *output)
{
    unsigned char hash[SHA_DIGEST_LENGTH];
    SHA1(key, n, hash);


    BIO *bmem, *b64;
    BUF_MEM *bptr;

    b64 = BIO_new(BIO_f_base64());
    bmem = BIO_new(BIO_s_mem());
    b64 = BIO_push(b64, bmem);

    BIO_write(b64, hash, SHA_DIGEST_LENGTH);
    BIO_flush(b64);
    BIO_get_mem_ptr(b64, &bptr);
    memcpy(output, bptr->data, bptr->length);
    // 这里切记是bptr->length字符数组的长度
    output[bptr->length - 1] = 0;

    BIO_free_all(b64);

    return 0;
}

int handshake(struct Conn *conn)
{
    // handshake
    unsigned char output[WEBSOCKET_KEY_LENGTH] = {0};
    unsigned char input[WEBSOCKET_KEY_LENGTH] = {0};
    char *key = strstr(conn->rbuffer, "Sec-WebSocket-Key:");
    if (!key)
    {
        conn->wlength = 0;
        return 1;
    }
    key += 19;
    int i = 0;
    while (*key != 0 && *key != ' ' && *key != '
')
    {
        input[i++] = *key++;
    }
    strcpy((char *)&input[i], "258EAFA5-E914-47DA-95CA-C5AB0DC85B11");
    encode_key(input, strlen((char *)input), output);
    
    struct stat filestat = {0};
    int sended = snprintf(conn->wbuffer, BUFFER_LENGTH,
        "HTTP/1.1 101 Switching Protocols
"
        "Upgrade: websocket
"
        "Connection: Upgrade
"
        "Sec-WebSocket-Accept: %s

", (char *)output);

    printf("%s|||
", output);

    conn->wlength = sended;
    return 0;
}

int ws_request(struct Conn *conn)
{
    printf("<<<<, conn->rbuffer);
    if (conn->status == 0)
    {
        handshake(conn);
        conn->status = 1;
    }
    else if (conn->status == 1)
    {
        int ret = 0;
        conn->payload = decode_packet((unsigned char *)conn->rbuffer, conn->mask, conn->rlength, &ret);
        printf("data: %s, length: %d
", conn->payload, ret);
        conn->wlength = ret;
        conn->status = 2;
    }
    return 0;
}

int ws_response(struct Conn *conn)
{
    if (conn->status == 2)
    {
        conn->wlength = encode_packet(conn->wbuffer, conn->mask, conn->payload, conn->wlength);
        conn->status = 1;
    }

    conn->wbuffer[conn->wlength] = 0;
    printf(">>>>output>>>>
%s
", conn->wbuffer);
    return 0;
}

5. websocket传输协议实现

5.1 websocket帧格式
	  0                   1                   2                   3
      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
     +-+-+-+-+-------+-+-------------+-------------------------------+
     |F|R|R|R| opcode|M| Payload len |    Extended payload length    |
     |I|S|S|S|  (4)  |A|     (7)     |             (16/64)           |
     |N|V|V|V|       |S|             |   (if payload len==126/127)   |
     | |1|2|3|       |K|             |                               |
     +-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
     |     Extended payload length continued, if payload len == 127  |
     + - - - - - - - - - - - - - - - +-------------------------------+
     |                               |Masking-key, if MASK set to 1  |
     +-------------------------------+-------------------------------+
     | Masking-key (continued)       |          Payload Data         |
     +-------------------------------- - - - - - - - - - - - - - - - +
     :                     Payload Data continued ...                :
     + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
     |                     Payload Data continued ...                |
     +---------------------------------------------------------------+

rfc6455 5.2介绍了各个域的作用,对应的如果要实现该协议就要定义相关的结构体

struct _nty_ophdr {

	unsigned char opcode:4,
		 rsv3:1,
		 rsv2:1,
		 rsv1:1,
		 fin:1;
	unsigned char payload_length:7,
		mask:1;

} __attribute__ ((packed));

struct _nty_websocket_head_126 {
	unsigned short payload_length;
	char mask_key[4];
	unsigned char data[8];
} __attribute__ ((packed));

struct _nty_websocket_head_127 {

	unsigned long long payload_length;
	char mask_key[4];

	unsigned char data[8];
	
} __attribute__ ((packed));

typedef struct _nty_websocket_head_127 nty_websocket_head_127;
typedef struct _nty_websocket_head_126 nty_websocket_head_126;
typedef struct _nty_ophdr nty_ophdr;

__attribute__ ((packed)) 是 GNU C 编译器(GCC)的一个扩展,用于告诉编译器不对结构体的成员进行内存对齐。通常,编译器为了提高访问效率,会按照特定的字节对齐规则来放置结构体成员。使用 packed 属性后,编译器不会对齐字段,而是按照定义的顺序紧凑地存储它们,节省内存空间。

5.2 解包客户端数据

rfc6455 5.3规定了客户端向服务端发送的数据必须经过掩码加密,其原理是用8位的mask-key对原数据一次逐字节进行异或操作,这样加密和解密的过程是完全一样的。

在协议帧中masking-key有4字节,协议规定,对payload[i]对应的maskkey为masking-key[i mod 4],这样就可以写出其加解密算法了:

void demask(char *data,int len,char *mask){    
	int i;    
	for (i = 0;i < len;i ++)        
		*(data+i) ^= *(mask+(i%4));
}

这样对于服务端的解包操作,就是解密payload,拿到原数据。

char* decode_packet(unsigned char *stream, char *mask, int length, int *ret) {

	nty_ophdr *hdr =  (nty_ophdr*)stream;
	unsigned char *data = stream + sizeof(nty_ophdr);
	int size = 0;
	int start = 0;
	//char mask[4] = {0};
	int i = 0;

	if ((hdr->payload_length & 0x7F) == 126) {

		nty_websocket_head_126 *hdr126 = (nty_websocket_head_126*)data;
		size = hdr126->payload_length;
		
		for (i = 0;i < 4;i ++) {
			mask[i] = hdr126->mask_key[i];
		}
		
		start = 8;
		
	} else if ((hdr->payload_length & 0x7F) == 127) {

		nty_websocket_head_127 *hdr127 = (nty_websocket_head_127*)data;
		size = hdr127->payload_length;
		
		for (i = 0;i < 4;i ++) {
			mask[i] = hdr127->mask_key[i];
		}
		
		start = 14;

	} else {
		size = hdr->payload_length;

		memcpy(mask, data, 4);
		start = 6;
	}

	*ret = size;
	demask(stream+start, size, mask);

	return stream + start;
}
5.3 服务端发包

对于服务端的发包操作,只需要填充相应的协议字段即可,不需要掩码加密。

int encode_packet(char *buffer,char *mask, char *stream, int length) {

	nty_ophdr head = {0};
	head.fin = 1;
	head.opcode = 1;
	int size = 0;

	if (length < 126) {
		head.payload_length = length;
		memcpy(buffer, &head, sizeof(nty_ophdr));
		size = 2;
	} else if (length < 0xffff) {
		nty_websocket_head_126 hdr = {0};
		hdr.payload_length = length;
		memcpy(hdr.mask_key, mask, 4);

		memcpy(buffer, &head, sizeof(nty_ophdr));
		memcpy(buffer+sizeof(nty_ophdr), &hdr, sizeof(nty_websocket_head_126));
		size = sizeof(nty_websocket_head_126);
		
	} else {
		
		nty_websocket_head_127 hdr = {0};
		hdr.payload_length = length;
		memcpy(hdr.mask_key, mask, 4);
		
		memcpy(buffer, &head, sizeof(nty_ophdr));
		memcpy(buffer+sizeof(nty_ophdr), &hdr, sizeof(nty_websocket_head_127));

		size = sizeof(nty_websocket_head_127);
		
	}

	memcpy(buffer+2, stream, length);

	return length + 2;
}

学习参考

学习更多相关知识请参考零声 github。

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

搜索文章

Tags

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