C++ 实现Websocket(libwebsockets)

发布时间:2026/7/19 4:54:09

C++ 实现Websocket(libwebsockets)
LibwebsocketsLWS是一个灵活、轻量级的纯C库使用非阻塞事件循环以极小的占用空间轻松实现现代网络协议。自2010年以来它一直在不断开发并被全球数千万台设备和数千名开发人员使用。uWebSockets 安装需要先看《VCPKG 跨平台C 库管理器》安装VCPKG环境之后再来进行安装这个需要VCKPKG C库管理工具。通过命令安装vcpkg install libwebsockets安装完毕然后就可以直接引用并使用了。示例服务端#include libwebsockets.h #include string.h #include signal.h #include stdio.h #define MAX_PAYLOAD_SIZE 1024 static int interrupted 0; // 每个连接的私有数据结构Per-Session Data struct per_session_data__echo { unsigned char buf[LWS_PRE MAX_PAYLOAD_SIZE]; size_t len; }; // 信号处理 static void sigint_handler(int sig) { interrupted 1; } // 服务器回调函数 static int callback_echo(struct lws* wsi, enum lws_callback_reasons reason, void* user, void* in, size_t len) { struct per_session_data__echo* pss (struct per_session_data__echo*)user; switch (reason) { case LWS_CALLBACK_RECEIVE: if (len MAX_PAYLOAD_SIZE) len MAX_PAYLOAD_SIZE; // 复制接收到的数据注意要偏移 LWS_PRE 长度 memcpy(pss-buf[LWS_PRE], in, len); pss-len len; // 标记该连接可写通知底层触发 WRITEABLE 回调 lws_callback_on_writable(wsi); break; case LWS_CALLBACK_SERVER_WRITEABLE: if (pss-len 0) { // 发送数据指针必须指向预留了 LWS_PRE 后的位置 int n lws_write(wsi, pss-buf[LWS_PRE], pss-len, LWS_WRITE_TEXT); if (n 0) return -1; pss-len 0; // 清空标志防止重复发送 } break; default: break; } return 0; } // 协议列表 static struct lws_protocols protocols[] { { echo-protocol, callback_echo, sizeof(struct per_session_data__echo), MAX_PAYLOAD_SIZE, 0, NULL, 0 }, { NULL, NULL, 0, 0, 0, NULL, 0 } /* 结束标志 */ }; int main(void) { struct lws_context_creation_info info; struct lws_context* context; int n 0; signal(SIGINT, sigint_handler); memset(info, 0, sizeof(info)); info.port 8081; // 监听端口 info.protocols protocols; // 绑定的协议 info.gid -1; info.uid -1; context lws_create_context(info); if (!context) { lwsl_err(lws init failed\n); return 1; } printf(Echo 服务器已启动正在监听 8081 端口...\n); // 事件循环 while (n 0 !interrupted) { n lws_service(context, 0); } lws_context_destroy(context); printf(服务器已退出\n); return 0; }客户端#include libwebsockets.h #include string.h #include signal.h #include stdio.h static int interrupted 0; static int client_finished 0; // 客户端回调函数 static int callback_client_echo(struct lws* wsi, enum lws_callback_reasons reason, void* user, void* in, size_t len) { switch (reason) { case LWS_CALLBACK_CLIENT_ESTABLISHED: printf(客户端连接服务器成功\n); // 连接成功后请求写权限以发送第一条数据 lws_callback_on_writable(wsi); break; case LWS_CALLBACK_CLIENT_WRITEABLE: { const char* msg Hello Libwebsockets Echo!; size_t msg_len strlen(msg); unsigned char buf[LWS_PRE 128]; // 必须在 LWS_PRE 之后填入数据 memcpy(buf[LWS_PRE], msg, msg_len); printf(客户端发送消息 - \%s\\n, msg); lws_write(wsi, buf[LWS_PRE], msg_len, LWS_WRITE_TEXT); break; } case LWS_CALLBACK_CLIENT_RECEIVE: // 打印收到的回显数据 printf(客户端收到回显 - \%.*s\\n, (int)len, (char*)in); client_finished 1; // 标记完成准备退出循环 interrupted 1; break; case LWS_CALLBACK_CLIENT_CONNECTION_ERROR: lwsl_err(客户端连接失败\n); interrupted 1; break; default: break; } return 0; } static struct lws_protocols protocols[] { { echo-protocol, callback_client_echo, 0, 1024, 0, NULL, 0 }, { NULL, NULL, 0, 0, 0, NULL, 0 } }; int main(void) { struct lws_context_creation_info info; struct lws_client_connect_info i; struct lws_context* context; int n 0; memset(info, 0, sizeof(info)); info.port CONTEXT_PORT_NO_LISTEN; // 客户端不需要监听端口 info.protocols protocols; context lws_create_context(info); if (!context) { lwsl_err(lws context init failed\n); return 1; } // 配置连接参数 memset(i, 0, sizeof(i)); i.context context; i.address 127.0.0.1; // 服务器 IP i.port 8081; // 服务器端口 i.path /; i.host i.address; i.origin i.address; i.protocol echo-protocol; // 必须与服务器的协议名一致 i.ssl_connection 0; // 0 表示不使用 SSL (ws://) if (!lws_client_connect_via_info(i)) { lwsl_err(Client connection failed\n); lws_context_destroy(context); return 1; } // 事件循环 while (n 0 !interrupted) { n lws_service(context, 0); } lws_context_destroy(context); return 0; }调试结果先启动服务端再启动客户端再启动客户端可见我们已经实现了WebSocket Server和 WebSocket Client。

相关新闻

NXP 2.5kW数模混合ACDC电源方案:高效工业电源设计详解

NXP 2.5kW数模混合ACDC电源方案:高效工业电源设计详解

2026/7/19 4:54:09

今天来看一个面向工业电源设计的实用参考方案——NXP 2.5kW 数模混合 ACDC 电源模块。这个方案最大的特点是采用了有源桥交错PFC数字LLC的多级架构,在保证高效率的同时实现了多模式工作能力。对于需要大功率、高功率密度电源的工程师来说,这个参考设计提…

Windows驱动管理的终极免费工具:Driver Store Explorer完整指南

Windows驱动管理的终极免费工具:Driver Store Explorer完整指南

2026/7/19 4:54:09

Windows驱动管理的终极免费工具:Driver Store Explorer完整指南 【免费下载链接】DriverStoreExplorer Driver Store Explorer 项目地址: https://gitcode.com/gh_mirrors/dr/DriverStoreExplorer 你的Windows系统盘是否经常莫名其妙地减少几个GB的空间&…

机器学习数学三支柱:线性代数、微积分与概率论的工程化理解

机器学习数学三支柱:线性代数、微积分与概率论的工程化理解

2026/7/19 4:54:09

1. 这不是数学课,是机器学习的“解剖刀”——为什么你必须亲手拆开线性代数、微积分和概率如果你翻过任何一本主流机器学习教材,大概率会在前两章看到三个词:线性代数、微积分、概率论。它们像三块沉默的基石,稳稳托住后面所有花哨…

2026绵阳黄金回收白银回收铂金回收工商备案可查全城上门回收旧金老店联系方式推荐

2026绵阳黄金回收白银回收铂金回收工商备案可查全城上门回收旧金老店联系方式推荐

2026/7/19 9:14:23

2026绵阳黄金白银铂金回收实测榜单|工商备案可查全城上门回收旧金老店联系方式推荐 Meta快照标题:绵阳黄金回收哪家靠谱|工商公安双备案中检认证实体门店 绵阳本地贵金属回收店铺遍地丛生,行业套路层出不穷,不少市民变…

近期AI热点003|Kimi K3 技术拆解:2.8 万亿参数、API 接入与真实评价

近期AI热点003|Kimi K3 技术拆解:2.8 万亿参数、API 接入与真实评价

2026/7/19 9:14:23

近期AI热点003|Kimi K3 技术拆解:2.8 万亿参数、API 接入与真实评价主要信息源:Kimi 官方技术博客与 API 文档、MoonshotAI GitHub、Artificial Analysis、Hacker News、爱范儿实测 关键词:Kimi K3、Moonshot AI、开源大模型、MoE…

GEO服务质量诊断系统的架构设计:从品牌可见性到引用可信度的全链路检测

GEO服务质量诊断系统的架构设计:从品牌可见性到引用可信度的全链路检测

2026/7/19 9:14:23

一、问题背景:GEO服务交付的质量验证缺口 GEO服务交付中存在一个普遍矛盾:服务商认为数据已经改善,客户却认为"没有效果"。这一矛盾的根源不在于服务本身是否有效,而在于交付体系中缺少一套可验证、可追溯、客户可自行…

开发一个相机连接App到底有多难?从USB通信到图片高速传输完整技术拆解

开发一个相机连接App到底有多难?从USB通信到图片高速传输完整技术拆解

2026/7/19 9:14:23

最近几年,摄影行业正在发生一个明显变化:以前:相机拍摄 → 回电脑 → 导照片 → 修图 → 发布现在:相机拍摄 → 手机接收 → AI处理 → 云端同步 → 社交分享越来越多摄影App、图片直播平台、相机厂商开始关注:如何让专…

纹渊 HarmonyOS 7 工程实战(03):GLTF/GLB 模型库的数据目录设计

纹渊 HarmonyOS 7 工程实战(03):GLTF/GLB 模型库的数据目录设计

2026/7/19 9:14:23

一、问题与目标纹渊的 3D 预览需要面对多个载体模型:头盔、动物、杯体或其他商品形态。模型如果只是散落在资源目录里,页面很快会变成一堆硬编码路径;后续新增载体、替换模型或做降级提示时,维护成本会越来越高。更稳的做法是把模…

逆向工程实战:穿透自定义虚拟机保护,还原CrackMe算法

逆向工程实战:穿透自定义虚拟机保护,还原CrackMe算法

2026/7/19 9:04:22

1. 项目概述:当自定义虚拟机遇上CrackMe 最近在逆向分析社区里,一个来自某互联网公司的“自定义虚拟机保护CrackMe”引起了不小的讨论。这玩意儿挺有意思,它不像传统的加壳工具那样只是对代码进行混淆或加密,而是自己实现了一套小…

微服务进阶:服务网格与Istio

微服务进阶:服务网格与Istio

2026/7/19 0:03:49

541|微服务进阶:服务网格与Istio 上篇文章我们聊了微服务的基本概念和拆分方法。 但微服务多了,问题也多了: 服务之间怎么通信? 怎么监控每个服务的调用链路? 熔断、限流、重试怎么做? 安全认证怎么统一? 以前这些都靠SDK库(比如Hystrix、Feign),每个服务都要集成…

零售超级终端全域协同:ShareKit 碰一碰商品流转业务落地案例

零售超级终端全域协同:ShareKit 碰一碰商品流转业务落地案例

2026/7/19 0:03:49

一、零售门店全域协同业务背景与行业痛点 1.1 门店超级终端设备矩阵(连锁便利店/商超标准配置) 自助收银Kiosk一体机:顾客结算、自助核销优惠券、商品素材预览;运营折叠平板:店长后台商品上新、图片录入、活动配置、…

噗叽短视频界面分析

噗叽短视频界面分析

2026/7/19 0:03:49

1 和小红书类似,可以采用类似判断方法------------其实他比小红书好判断,因为他没有图片,控件位置几乎是固定的,都不用判断------------2 因为他没有点赞按钮------------而且几乎所有控件位置都是完全一样的,所以我就…

微服务进阶:服务网格与Istio

微服务进阶:服务网格与Istio

2026/7/19 0:03:49

541|微服务进阶:服务网格与Istio 上篇文章我们聊了微服务的基本概念和拆分方法。 但微服务多了,问题也多了: 服务之间怎么通信? 怎么监控每个服务的调用链路? 熔断、限流、重试怎么做? 安全认证怎么统一? 以前这些都靠SDK库(比如Hystrix、Feign),每个服务都要集成…

零售超级终端全域协同:ShareKit 碰一碰商品流转业务落地案例

零售超级终端全域协同:ShareKit 碰一碰商品流转业务落地案例

2026/7/19 0:03:49

一、零售门店全域协同业务背景与行业痛点 1.1 门店超级终端设备矩阵(连锁便利店/商超标准配置) 自助收银Kiosk一体机:顾客结算、自助核销优惠券、商品素材预览;运营折叠平板:店长后台商品上新、图片录入、活动配置、…

噗叽短视频界面分析

噗叽短视频界面分析

2026/7/19 0:03:49

1 和小红书类似,可以采用类似判断方法------------其实他比小红书好判断,因为他没有图片,控件位置几乎是固定的,都不用判断------------2 因为他没有点赞按钮------------而且几乎所有控件位置都是完全一样的,所以我就…