C++11实现TCP网络通讯服务端处理逻辑简化版

news2025/6/7 0:18:48

以下是使用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;
}

关键实现细节说明:

  1. 缓冲区管理
    • 使用std::vector<char>作为动态缓冲区,自动管理内存
    • 预分配双倍数据包大小空间(PACKET_SIZE * 2)减少内存重分配
  2. 帧头检测
    • find_frame_header函数逐字节比对帧头模式
    • 使用uint8_t类型转换避免符号扩展问题
    • 精确匹配连续3字节的帧头序列
  3. 粘包处理
    • 当未找到完整帧头时,保留最后2字节(HEADER_SIZE - 1)防止丢弃可能的帧头前缀
    • 找到帧头后检查剩余数据是否满足完整数据包长度
  4. 数据包处理
    • 检测到完整数据包后调用process_packet处理
    • 每次处理后从缓冲区移除已处理数据(包含帧头)
  5. 异常处理
    • 检测客户端断开连接(recv返回0)
    • 基础错误检查(socket创建、绑定、监听等)

使用注意事项:

  1. 编译时需要链接网络库(Linux下添加-lpthread参数)
  2. 实际使用时需完善以下部分:
    • process_packet函数中的业务逻辑
    • 添加校验和验证(如协议需要)
    • 多客户端支持(可通过多线程/select/epoll实现)
    • 错误日志记录
    • 性能优化(环形缓冲区、零拷贝等)

该实现能够有效处理TCP粘包问题,确保完整数据包的接收和处理,适用于需要固定长度数据包传输的场景。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2402273.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

LabVIEW的AMC架构解析

此LabVIEW 程序基于消息队列&#xff08;Message Queue&#xff09;机制构建 AMC 架构&#xff0c;核心包含消息生成&#xff08;MessageGenerator &#xff09;与消息处理&#xff08;Message Processor &#xff09;两大循环&#xff0c;通过队列传递事件与指令&#xff0c;实…

MySQL 索引:为使用 B+树作为索引数据结构,而非 B树、哈希表或二叉树?

在数据库的世界里&#xff0c;性能是永恒的追求。而索引&#xff0c;作为提升查询速度的利器&#xff0c;其底层数据结构的选择至关重要。如果你深入了解过 MySQL&#xff08;尤其是其主流存储引擎 InnoDB&#xff09;&#xff0c;你会发现它不约而同地选择了 B树 作为索引的主…

ubuntu屏幕复制

在ubnuntu20中没有办法正常使用镜像功能,这里提供一下复制屏幕的操作. 使用xrandr查看所有的显示器情况 这里我发现自己的电脑没有办法直接设置分辨率,但是外接的显示器可以设置,从命令行来说就是设置: xrandr --output HDMI-0 --mode 1920x1080那怎么样才能将原生电脑屏幕换…

Spring WebFlux 整合AI大模型实现流式输出

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

验证电机理论与性能:电机试验平板提升测试效率

电机试验平板提升测试效率是验证电机理论与性能的重要环节之一。通过在平板上进行电机试验&#xff0c;可以对电机的性能参数进行准确测量和分析&#xff0c;从而验证电机的理论设计是否符合实际表现。同时&#xff0c;提升测试效率可以加快试验过程&#xff0c;节约时间和成本…

Simplicity studio SDK下载和安装,创建工程

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

OpenCV——Mac系统搭建OpenCV的Java环境

这里写目录标题 一、源码编译安装1.1、下载源码包1.2、cmake安装1.3、java配置1.4、测试 二、Maven引入2.1、添加Maven依赖2.2、加载本地库 一、源码编译安装 1.1、下载源码包 官网下载opencv包&#xff1a;https://opencv.org/releases/ 以4.6.0为例&#xff0c;下载解压后&…

【设计模式-3.4】结构型——代理模式

说明&#xff1a;说明&#xff1a;本文介绍结构型设计模式之一的代理模式 定义 代理模式&#xff08;Proxy Pattern&#xff09;指为其他对象提供一种代理&#xff0c;以控制对这个对象的访问&#xff0c;属于结构型设计模式。&#xff08;引自《设计模式就该这样学》P158&am…

50天50个小项目 (Vue3 + Tailwindcss V4) ✨ | Sound Board(音响控制面板)

&#x1f4c5; 我们继续 50 个小项目挑战&#xff01;—— SoundBoard 组件 仓库地址&#xff1a;https://github.com/SunACong/50-vue-projects 项目预览地址&#xff1a;https://50-vue-projects.vercel.app/ &#x1f3af; 组件目标 实现一个响应式按钮面板&#xff0c;点…

关于大数据的基础知识(一)——定义特征结构要素

成长路上不孤单&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a; 【14后&#x1f60a;///计算机爱好者&#x1f60a;///持续分享所学&#x1f60a;///如有需要欢迎收藏转发///&#x1f60a;】 今日分享关于大数据的基础知识&#xff08;一&a…

chrome使用手机调试触屏web

chrome://inspect/#devices 1、手机开启调试模式、打开usb调试 2、手机谷歌浏览器打开网站 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/f1ef2d2c017c477ba55a57338ae13fc8.jpeg#pic_center 使用谷歌浏览器打开chrome://inspect/#devices 刷新浏览器点击inspect…

python版若依框架开发:项目结构解析

python版若依框架开发 从0起步&#xff0c;扬帆起航。 python版若依部署代码生成指南&#xff0c;迅速落地CURD&#xff01;项目结构解析 文章目录 python版若依框架开发前端后端 前端 后端

day34- 系统编程之 网络编程(TCP)

一、补充 ip地址:除了本机地址如&#xff1a;192.168.0.151还可以使用&#xff08;自己测试&#xff09;本地回环地址&#xff08;127.0.0.1&#xff09;或者使用htonl(INADDR_ANY)&#xff1b; 二、模式 C/S 模式 ->服务器/客户端模型&#xff1a;TCP传输控制协议 2.1 …

鸿蒙jsonToArkTS_工具exe版本来了

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

DeviceNet转Modbus TCP网关的远程遥控接收端连接研究

在港口码头作业中&#xff0c;遥控器因其精确的操作控制和稳定的性能&#xff0c;已成为起重机货物装卸作业的重要辅助工具。然而&#xff0c;在某港口码头实施无线遥控器远程控制掘进机的过程中&#xff0c;由于通信协议的不兼容&#xff0c;遭遇了技术难题。具体而言&#xf…

ASP.NET Core 中间件深度解析:构建灵活高效的请求处理管道

在现代Web应用开发中&#xff0c;请求处理管道的设计和实现至关重要。ASP.NET Core通过其中间件(Middleware)系统提供了一种高度灵活、可扩展的方式来构建请求处理管道。本文将全面深入地探讨ASP.NET Core中间件的概念、工作原理、实现方式以及最佳实践&#xff0c;帮助开发者掌…

从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 位主发送序列…

文件索引:数组、二叉树、二叉排序树、平衡树、红黑树、B树、B+树

参考链接&#xff1a;https://www.bilibili.com/video/BV1mY4y1W7pS 数据结构可视化工具&#xff1a;https://www.cs.usfca.edu/~galles/visualization/Algorithms.html 问题引出&#xff1a;一般是什么原因导致从磁盘查找数据效率低&#xff1f; 通过索引来更快的查询数据&a…

《仿盒马》app开发技术分享-- 商品搜索页(顶部搜索bar热门搜索)(端云一体)

开发准备 随着开发功能的逐渐深入&#xff0c;我们的应用逐渐趋于完善&#xff0c;现在我们需要继续在首页给没有使用按钮以及组件添加对应的功能&#xff0c;这一节我们要实现的功能是商品搜索页面&#xff0c;这个页面我们从上到下开始实现功能&#xff0c;首先就是一个搜索…