资源简介
c++服务器 拆包粘包 过程
千万别问我是基于TCP的还是UDP的...
代码片段和文件信息
#include “stdafx.h“
#include “ReceiveManager.h“
#include “boost\mpl\assert.hpp“
#include “boost\bind.hpp“
#include “msg\PerHandleData.h“
#include “msg\Packet.h“
ReceiveManager::ReceiveManager(unsigned int recvBufferSize)
:SendOrRecvMngbase(recvBufferSize)
_socket_manager(NULL)
{
_msg_queue = new MessageQueue(recvBufferSize);
if(_msg_queue != NULL){
if(!_msg_queue->Init(boost::bind(&ReceiveManager::Dispatch this _1))){
throw;
}
}
else{
throw;
}
#ifdef SIC
printf(“receive manager has been launched.\n“);
#endif
}
ReceiveManager::~ReceiveManager(void)
{
//此类对象由@class Acceptor @class Connector管理和维护
//_socket_manager = NULL;
SAFE_DELETE(_msg_queue);
}
void ReceiveManager::AsynReceive( mc_system_msg::PPerHandleData handledata const boost::system::error_code& error std::size_t bytes_transferred )
{
//在拆包的时候,这个变量是有用的,因为拆包需要移动handledata->_buffer指针,使之不断指向下一个包
//当处理完毕后,需要对handledata->_buffer缓冲区指针还原,以免释放缓冲区时出现问题
char* tmpPtr = handledata->_buffer;
//设置总共收到的消息的长度,必须要用+=,而不是=
handledata->_offset += bytes_transferred;
if(Receive(handledata bytes_transferred))
{
//投递接收操作
PostReceive(handledata->Socket());
}
//防止handledata->_buffer指针在Receive中被改变还原指针值,希望指针被正确的释放
handledata->_buffer = tmpPtr;
ReleaseMemory(handledata);
}
///
/// 此过程主要处理TCP消息的拆包和粘包过程,把处理完整的消息加入到消息队列
///
/// The handledata.
/// The bytes_transferred.
/// int.
bool ReceiveManager::Receive( mc_system_msg::PPerHandleData handledata std::size_t bytes_transferred )
{
if(bytes_transferred == 0){
//DoData(handledata 0);
_msg_queue->Add(handledata);
return false;
}
using namespace mc_system_msg;
do
{
PPacket tmpPacket = (PPacket)handledata->_buffer;
if(handledata->_offset < PACKET_SIZE){
//消息不全,跳转到[2]继续读取消息
goto FALG_4;
}
else if(tmpPacket->_the_packet_header_size != PACKET_SIZE){
return false;
}
/*[1]*/if(tmpPacket->_the_whole_packet_size == handledata->_offset){
//DoData(handledata bytes_transferred);
_msg_queue->Add(handledata);
return true;
}
/*[2]*/else if(handledata->_offset < tmpPacket->_the_whole_packet_size){
/*
* 代码执行到这里,说明已收到的数据不是一个完整的包,需要再次接收剩下的数据,这里或许有一个疑问,为什么重新获取数据句柄?
* 原因在于下面一个判断[3]:
* else if(handledata->_offset > tmpPacket->_the_whole_packet_size && tmpPacket->_the_whole_packet_size != 0)
* 这个判断的意思是,收到的数据是几个消息包的集合,需要拆分处理,那么可能正好是3个包的集合,也可能是3个半的消息包的集合,这样,剩下的1/2
* 数据包的处理将会走到这个if里,这时,并不能保证handledata->_buffer指针,还指在handledata->_buffer的头部,或许已经移动到了中部,
* 尾部等,基于这个原因,所以再次申请一个数据句柄,用于投递接收剩下的数据。
*
* 看了以上的话,那为什么不定义一个临时指针?这里可以不用重新申请数据句柄吗?
* 答:就算定义一个临时指针,那么在【3个半的消息包的集合,这样,剩下的1/2数据包的处理将会走到这个if里】这种情况下,还要把剩下的数据移动到
* handledata->_buffer头部,然后再去投递接收剩下的数据,这样的一个操作过程不比重新申请一个数据句柄简单
*/
FALG_4:
mc_system_msg::PPerHandleData tmp_perHandledata = GetData(hand
属性 大小 日期 时间 名称
----------- --------- ---------- ----- ----
文件 1505 2014-08-12 14:28 PerHandleData.h
文件 4655 2014-08-18 08:52 ReceiveManager.cpp
文件 2854 2014-08-12 14:35 ReceiveManager.h
- 上一篇:C++PCM音频格式录音双缓存MFC版本
- 下一篇:C语言图书管理系统代码.doc
相关资源
- 超完美大学C语言期末复习题库,附答
- 操作系统 请求分页式存储管理的地址
- WEBRTC的混音过程分析.doc
- C++实战源码-使用递归过程实现阶乘运
- C++ 在复制文件的过程中显示进度条
- C++ 重命名存储过程
- C++ 监控上网过程
- C++ 在存储过程中使用RETURN定义返回值
- C++ 在存储过程中使用事务
- C++ 加密存储过程
- C++ 删除存储过程
- 应用随机过程_张帼奋.pdf
- 冒泡排序,完整实现排序过程
- Vc++服务器接受数据,发送数据
- 基于C++服务器和客户端聊天软件(V
- 个人通讯录管理系统C语言课程设计报
- 计算方法——迭代过程加速
- 要求演示二分法查找过程
- 达内培训机构最新录制C++班全过程视
评论
共有 条评论