C++11实现TCP网络通讯服务端处理逻辑简化版
以下是使用C++11实现的TCP服务端处理逻辑,包含循环读取数据、帧头检测(AABBCC)及4376字节数据包处理:
cpp
#include <iostream> | |
#include <vector> | |
#include <cstring> | |
#include <unistd.h> | |
#include <arpa/inet.h> | |
#include <sys/socket.h> | |
constexpr size_t PACKET_SIZE = 4376; // 完整数据包大小(含3字节帧头) | |
constexpr size_t HEADER_SIZE = 3; // 帧头大小 | |
constexpr uint8_t FRAME_HEADER[] = {0xAA, 0xBB, 0xCC}; // 帧头标识 | |
// 查找缓冲区中的帧头位置 | |
auto find_frame_header(const std::vector<char>& buffer) { | |
for (size_t i = 0; i <= buffer.size() - HEADER_SIZE; ++i) { | |
bool match = true; | |
for (size_t j = 0; j < HEADER_SIZE; ++j) { | |
if (static_cast<uint8_t>(buffer[i+j]) != FRAME_HEADER[j]) { | |
match = false; | |
break; | |
} | |
} | |
if (match) return buffer.begin() + i; | |
} | |
return buffer.end(); | |
} | |
// 数据包处理函数(示例) | |
void process_packet(const char* data) { | |
// 这里添加实际业务逻辑 | |
std::cout << "Received valid packet!" << std::endl; | |
} | |
int main() { | |
// 1. 创建TCP socket | |
int server_fd = socket(AF_INET, SOCK_STREAM, 0); | |
if (server_fd == -1) { | |
std::cerr << "Socket creation failed!" << std::endl; | |
return 1; | |
} | |
// 2. 绑定地址 | |
sockaddr_in server_addr{}; | |
server_addr.sin_family = AF_INET; | |
server_addr.sin_addr.s_addr = INADDR_ANY; | |
server_addr.sin_port = htons(8080); // 监听端口 | |
if (bind(server_fd, (sockaddr*)&server_addr, sizeof(server_addr)) == -1) { | |
std::cerr << "Bind failed!" << std::endl; | |
close(server_fd); | |
return 1; | |
} | |
// 3. 开始监听 | |
if (listen(server_fd, 5) == -1) { | |
std::cerr << "Listen failed!" << std::endl; | |
close(server_fd); | |
return 1; | |
} | |
// 4. 接受客户端连接 | |
sockaddr_in client_addr{}; | |
socklen_t addr_len = sizeof(client_addr); | |
int client_fd = accept(server_fd, (sockaddr*)&client_addr, &addr_len); | |
if (client_fd == -1) { | |
std::cerr << "Accept failed!" << std::endl; | |
close(server_fd); | |
return 1; | |
} | |
std::vector<char> buffer; | |
buffer.reserve(PACKET_SIZE * 2); // 预留双倍数据包空间 | |
while (true) { | |
// 5. 循环接收数据 | |
char temp_buf[1024]; | |
ssize_t bytes_received = recv(client_fd, temp_buf, sizeof(temp_buf), 0); | |
if (bytes_received <= 0) { | |
std::cout << "Connection closed by client" << std::endl; | |
break; | |
} | |
// 将接收数据追加到缓冲区 | |
buffer.insert(buffer.end(), temp_buf, temp_buf + bytes_received); | |
// 6. 处理缓冲区数据 | |
while (true) { | |
auto header_pos = find_frame_header(buffer); | |
if (header_pos == buffer.end()) { | |
// 未找到帧头,保留最后两个字节防止丢弃可能的帧头前缀 | |
if (buffer.size() >= HEADER_SIZE - 1) { | |
buffer.erase(buffer.begin(), buffer.end() - (HEADER_SIZE - 1)); | |
} else { | |
buffer.clear(); | |
} | |
break; | |
} | |
// 检查剩余数据是否足够 | |
if (buffer.end() - header_pos >= PACKET_SIZE) { | |
// 7. 处理完整数据包 | |
process_packet(&*header_pos); | |
// 8. 移除已处理数据(包含帧头) | |
buffer.erase(buffer.begin(), header_pos + PACKET_SIZE); | |
} else { | |
// 数据不足,等待下次接收 | |
break; | |
} | |
} | |
} | |
// 清理资源 | |
close(client_fd); | |
close(server_fd); | |
return 0; | |
} |
关键实现细节说明:
- 缓冲区管理:
- 使用
std::vector<char>
作为动态缓冲区,自动管理内存 - 预分配双倍数据包大小空间(
PACKET_SIZE * 2
)减少内存重分配
- 使用
- 帧头检测:
find_frame_header
函数逐字节比对帧头模式- 使用
uint8_t
类型转换避免符号扩展问题 - 精确匹配连续3字节的帧头序列
- 粘包处理:
- 当未找到完整帧头时,保留最后2字节(
HEADER_SIZE - 1
)防止丢弃可能的帧头前缀 - 找到帧头后检查剩余数据是否满足完整数据包长度
- 当未找到完整帧头时,保留最后2字节(
- 数据包处理:
- 检测到完整数据包后调用
process_packet
处理 - 每次处理后从缓冲区移除已处理数据(包含帧头)
- 检测到完整数据包后调用
- 异常处理:
- 检测客户端断开连接(
recv
返回0) - 基础错误检查(socket创建、绑定、监听等)
- 检测客户端断开连接(
使用注意事项:
- 编译时需要链接网络库(Linux下添加
-lpthread
参数) - 实际使用时需完善以下部分:
process_packet
函数中的业务逻辑- 添加校验和验证(如协议需要)
- 多客户端支持(可通过多线程/select/epoll实现)
- 错误日志记录
- 性能优化(环形缓冲区、零拷贝等)
该实现能够有效处理TCP粘包问题,确保完整数据包的接收和处理,适用于需要固定长度数据包传输的场景。
相关文章:
C++11实现TCP网络通讯服务端处理逻辑简化版
以下是使用C11实现的TCP服务端处理逻辑,包含循环读取数据、帧头检测(AABBCC)及4376字节数据包处理: cpp #include <iostream>#include <vector>#include <cstring>#include <unistd.h>#include <arp…...
python3.9带 C++绑定的基础镜像
FROM ubuntu:20.04 # 设置非交互式环境变量(避免apt安装时提示时区选择) ENV DEBIAN_FRONTENDnoninteractive RUN ln -fs /usr/share/zoneinfo/Asia/Shanghai /etc/localtime # 安装基础编译工具和依赖 # 添加Python 3.9 PPA并安装依赖 RUN apt-get upda…...
Elasticsearch中的语义搜索(Semantic Search)介绍
Elasticsearch中的**语义搜索(Semantic Search)**是一种基于文本语义理解的搜索技术,它能够超越传统的关键词匹配,识别查询与文档之间的语义相关性,从而提供更精准、更符合用户意图的搜索结果。这种技术通过捕捉文本背后的含义、上下文和概念关联,解决了传统搜索中常见的…...

LabVIEW的AMC架构解析
此LabVIEW 程序基于消息队列(Message Queue)机制构建 AMC 架构,核心包含消息生成(MessageGenerator )与消息处理(Message Processor )两大循环,通过队列传递事件与指令,实…...

MySQL 索引:为使用 B+树作为索引数据结构,而非 B树、哈希表或二叉树?
在数据库的世界里,性能是永恒的追求。而索引,作为提升查询速度的利器,其底层数据结构的选择至关重要。如果你深入了解过 MySQL(尤其是其主流存储引擎 InnoDB),你会发现它不约而同地选择了 B树 作为索引的主…...

ubuntu屏幕复制
在ubnuntu20中没有办法正常使用镜像功能,这里提供一下复制屏幕的操作. 使用xrandr查看所有的显示器情况 这里我发现自己的电脑没有办法直接设置分辨率,但是外接的显示器可以设置,从命令行来说就是设置: xrandr --output HDMI-0 --mode 1920x1080那怎么样才能将原生电脑屏幕换…...
Flutter嵌入式开发实战 ——从树莓派到智能家居控制面板,打造工业级交互终端
一、为何选择Flutter开发嵌入式设备? 1. 跨平台能力降维打击 特性传统方案Flutter方案开发效率需分别开发Android/Linux一套代码多端部署内存占用200MB (QtWeb引擎)<80MB (Release模式)热重载支持不支持支持 2. 工业级硬件支持实测 树莓派4B:1080…...

Spring WebFlux 整合AI大模型实现流式输出
前言 最近赶上AI的热潮,很多业务都在接入AI大模型相关的接口去方便的实现一些功能,后端需要做的是接入AI模型接口,并整合成流式输出到前端,下面有一些经验和踩过的坑。 集成 Spring WebFlux是全新的Reactive Web技术栈…...

验证电机理论与性能:电机试验平板提升测试效率
电机试验平板提升测试效率是验证电机理论与性能的重要环节之一。通过在平板上进行电机试验,可以对电机的性能参数进行准确测量和分析,从而验证电机的理论设计是否符合实际表现。同时,提升测试效率可以加快试验过程,节约时间和成本…...
Vue.js应用结合Redis数据库:实践与优化
一、概述 Vue.js是一个用于构建用户界面的渐进式JavaScript框架,适用于开发单页面应用(SPA)。Redis是一个高性能的内存数据结构存储,用作数据库、缓存和消息中间件。将Vue.js与Redis结合,可以实现高效的数据管理和快速…...

Simplicity studio SDK下载和安装,创建工程
下载SDK工具地址 Simplicity Studio - Silicon Labs 选择适合自己电脑的版本。 这个就使用你自己的邮箱注册一个就可以了,我是用的公司邮箱注册的。 下载完成: 安装 下载完成后右键点击安装,一路下一步 安装完成后,程序自动打…...

OpenCV——Mac系统搭建OpenCV的Java环境
这里写目录标题 一、源码编译安装1.1、下载源码包1.2、cmake安装1.3、java配置1.4、测试 二、Maven引入2.1、添加Maven依赖2.2、加载本地库 一、源码编译安装 1.1、下载源码包 官网下载opencv包:https://opencv.org/releases/ 以4.6.0为例,下载解压后&…...
更新Java的环境变量后VScode/cursor里面还是之前的环境变量
最近我就遇到这个问题,这个一般是安装了多个版本的Java,并设置好环境变量,但VScode/cursor内部环境变量却没有改变 解决办法 打开设置,或者直接快捷键CTRL,搜索Java:Home编辑settings.json文件 把以下部分改为正确的…...

【设计模式-3.4】结构型——代理模式
说明:说明:本文介绍结构型设计模式之一的代理模式 定义 代理模式(Proxy Pattern)指为其他对象提供一种代理,以控制对这个对象的访问,属于结构型设计模式。(引自《设计模式就该这样学》P158&am…...
电脑频繁黑屏怎么办
有没有遇到过这种糟心事儿:正兴致勃勃地打游戏、赶方案,或者追着喜欢的剧,电脑突然黑屏了!而且还频繁出现,简直让人抓狂。今天咱们就来好好聊聊,电脑频繁黑屏到底该怎么办。 硬件问题排查 检查显示器连接…...

50天50个小项目 (Vue3 + Tailwindcss V4) ✨ | Sound Board(音响控制面板)
📅 我们继续 50 个小项目挑战!—— SoundBoard 组件 仓库地址:https://github.com/SunACong/50-vue-projects 项目预览地址:https://50-vue-projects.vercel.app/ 🎯 组件目标 实现一个响应式按钮面板,点…...

关于大数据的基础知识(一)——定义特征结构要素
成长路上不孤单😊😊😊😊😊😊 【14后😊///计算机爱好者😊///持续分享所学😊///如有需要欢迎收藏转发///😊】 今日分享关于大数据的基础知识(一&a…...

chrome使用手机调试触屏web
chrome://inspect/#devices 1、手机开启调试模式、打开usb调试 2、手机谷歌浏览器打开网站 
简述什么是Hbase数据库? Hbase是一个高可靠性、高性能、面向列、可伸缩的分布式存储系统,它利用HBase技术在HDFS上提供了类似于Bigtable的能力。换句话说,Hbase是Apache Hadoop生态系统中的一部分,可以为大数据应用提供快速的随机…...

python版若依框架开发:项目结构解析
python版若依框架开发 从0起步,扬帆起航。 python版若依部署代码生成指南,迅速落地CURD!项目结构解析 文章目录 python版若依框架开发前端后端 前端 后端...
国产linux系统(银河麒麟,统信uos)使用 PageOffice在线编辑word文件保存数据同时保存文件
在实际应用中,例如在线签订合同的时候,合同的签订日期,合同号等等这些信息既要保存到数据库,合同签订后又要将整个合同文件保存起来。这时候就需要用到PageOffice的保存数据区域数据的同时保存整个文件的功能。 后端代码 后端打…...

day34- 系统编程之 网络编程(TCP)
一、补充 ip地址:除了本机地址如:192.168.0.151还可以使用(自己测试)本地回环地址(127.0.0.1)或者使用htonl(INADDR_ANY); 二、模式 C/S 模式 ->服务器/客户端模型:TCP传输控制协议 2.1 …...

鸿蒙jsonToArkTS_工具exe版本来了
前言导读 相信大家在学习鸿蒙开发过程中最痛苦的就是编写model 类 特别是那种复杂的json的时候对不对, 这时候有一个自动化的工具给你生成model是不是很开心。我们今天要分享的就是这个工具 JsonToArkTs 的用法 工具地址 https://gitee.com/qiuyu123/jsontomodel…...

DeviceNet转Modbus TCP网关的远程遥控接收端连接研究
在港口码头作业中,遥控器因其精确的操作控制和稳定的性能,已成为起重机货物装卸作业的重要辅助工具。然而,在某港口码头实施无线遥控器远程控制掘进机的过程中,由于通信协议的不兼容,遭遇了技术难题。具体而言…...

ASP.NET Core 中间件深度解析:构建灵活高效的请求处理管道
在现代Web应用开发中,请求处理管道的设计和实现至关重要。ASP.NET Core通过其中间件(Middleware)系统提供了一种高度灵活、可扩展的方式来构建请求处理管道。本文将全面深入地探讨ASP.NET Core中间件的概念、工作原理、实现方式以及最佳实践,帮助开发者掌…...
开关机、重启、改密、登录:图解腾讯云CVM日常管理核心操作,轻松掌控你的云主机
更多服务器知识,尽在hostol.com 嘿,各位腾讯云的“新晋地主”们!恭喜你成功“开垦”了自己的第一片“云端沃土”——拥有了一台崭新的云服务器CVM!现在,这台CVM就像一部功能强大的超级智能电视,已经送到你…...

从0到1认识ElasticStack
一、ES集群部署 操作系统Ubuntu22.04LTS/主机名IP地址主机配置elk9110.0.0.91/244Core8GB100GB磁盘elk9210.0.0.92/244Core8GB100GB磁盘elk9310.0.0.93/244Core8GB100GB磁盘 1. 什么是ElasticStack? # 官网 https://www.elastic.co/ ElasticStack早期名称为elk。 elk分别…...

I2C 外设知识体系:从基础到 STM32 硬件实现
文章目录 I2C外设简介I2C 通信实现方式对比1. 软件模拟 I2C2. 硬件实现 I2C STM32 I2C 外设核心功能1. 硬件特性2. 寄存器与引脚 I2C框图一、引脚接口二、数据处理模块三、时钟控制模块四、控制逻辑模块五、辅助功能 I2C基本结构主机发送一、7 位主发送序列二、10 位主发送序列…...
vue和uniapp聊天页面右侧滚动条自动到底部
1.vue右侧滚动条自动到底部 <div ref"newMessage1"></div> <!-- 定义<div ref"newMessage1"></div>与<div v-for”item in list“>循环同级定义-->定义方法 scrollToBottomCenter(){this.$nextTick(() > {this.$re…...