C++|Tcp数据接收缓冲区数据优化处理

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第8天, 点击查看活动详情

上一篇文章中介绍了对于通信接收的数据如何筛选整包的逻辑,那么今天就对这筛选出来的包数据做优化处理,提高程序的性能。

首先,上这段未优化的数据处理代码~

int nTotalSize = 0;
while (this->JudgeValidData(vetRecvData, nTotalSize) == true)
	//这一条数据被处理之后,使用一个临时容器存储 处理的 通讯数据
	std::vector<char> vetValidData;
	char* chUseData = new char[nTotalSize];
	memset(chUseData, 0, nTotalSize);
	for (int i = 0; i < vetRecvData.size(); i++)
		if (i < nTotalSize)
			chUseData[i] = vetRecvData[i];
			vetValidData.push_back(vetRecvData[i]);
	//删除 存储所有接收字节的容器 中的数据
	vetRecvData.clear();
	vetRecvData = vetValidData; //重新更新数据信息
	//接收的是整包数据时,进行实际的数据处理
	ProcessingPancelValidData(chUseData, nTotalSize);
	delete[] chUseData;
	chUseData = nullptr;

这纯属小白操作,看到这段代码的时候我的第一反应就是性能太低了~

筛选出一组完整数据包后,为了从vetRecvData缓冲区中筛选出内容,直接采用了for循环遍历的方式,虽然这种方法也正确,但是比较消耗时间。

查询了vector的有哪些快速复制拷贝功能后,可以对for循环遍历的方式修改。

1:从缓冲区中截取出一组完整包数据

std::vector<char> vetUseData;
vetUseData.insert(vetUseData.end(), vetRecvData.begin(), vetRecvData.begin() + nTotalSize);

2:将剩余数据重新替换到缓冲区中

std::vector<char> vetValidData;
vetValidData.insert(vetValidData.end(), vetRecvData.begin() + nTotalSize, vetRecvData.end());
vetRecvData.clear();
vetRecvData = vetValiData;

3:vector<char>数据数据转成char*数据

char* chUseData = new char[nTotalSize];
memset(chUseData, 0, nTotalSize);		
memcpy(chUseData, &vetUseData[0], nTotalSize); //完整数据包
//整包数据处理
ProcessingPancelValidData(chUseData, nTotalSize);
delete[] chUseData;
chUseData = nullptr;

在进行转换过程中,memcpy这句代码是最核心的~大家一定不要搞错了。

到这里优化后的数据处理就完整了~

下面,我就来说一说我在进行优化时遇到的一些问题。

1:为什么在处理缓冲区数据时采用vector<char>方式?recv接收的时候不应该是char[]数组类型吗?

首先::recv函数确实是使用char[]进行接收的,转换成vector<char>类型,主要方便在JudgeValidData函数中做数据剔除数据,直接操作char[]的话,对于一些数组运用不熟悉的很容易造成越界,为了方便管理,就采用了容器的方式。

那么,必然存在char[]到vector<char>的转换。最菜鸟的做法就是逐个下标的转换,如下代码

for (int i = 0; i < nRecv; i++)
     vetRecvData.push_back(buff[i]);

这种for循环的方式很是浪费时间,那么我的优化方法是:

std::vector<char>  vData(buff, buff + nRecv);
vetRecvData.insert(vetRecvData.end(), vData.begin(), vData.end());

2:为什么完整包解析出来后,还需要转换成char*数组?

假设你的通信指令中,存在字符串数据时,比如说传输一个json串,经过一系列转码解析后,最终是需要展示一段字符串,解析包后再专场char*为了方便在截取出数据后,进行utf与unicode转码操作。

假设你的通信指令中,只是bool或者整型的简单指令时,就没必要进行转换了。

根据实际业务需求做特殊处理。

这里纯属为大家讲解下:如何将vector<char>转换成char*操作,需要的可以拿去了~

我是中国好公民st,一名C++开发程序猿~