真心求分析 TCP粘包问题 我有丢包 ,已经困惑通宵了

gjskxy 2011-03-29 01:43:39
真心求分析 TCP粘包问题 我有丢包 ,已经困惑通宵了
尤其是里面的 if ( 0x9F == pTempData[unLeftLen + 1] )...这一块合理吗




消息的结构:(head)9F 9F (len)0 0 0 5 (info)01 02 03 04 05
判断当前的解帧状态,包含三部分head、len、info
1、如果是在解头部,判断已经解帧的长度是否大于
(1) 如果小于头的长度,继续获取长度部分
(2) 如果大于头的长度,则获取消息len的长度
2、如果是在获取消息的len部分,判断已经解帧的长度是否大于
(1) 如果小于len的长度,继续获取len部分
(2) 如果大于len的长度,则判断len + 1位置是否是9F
1) 如果是9F,认为是完整的消息;
2) 如果不是9F,则认为是错误消息,从上次的9F的位置查找下一个头的位置
3) 找到则重复1的过程
3、如果是在解消息体部分
(1) 由于在2中已经向前看完了整个info部分,所以直接取出来就可以了

...全文
397 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhen3feng 2011-04-10
  • 打赏
  • 举报
回复

recv取出数据后通信缓冲区中就没有该数据了,所以“2) 如果不是9F,则认为是错误消息,从上次的9F的位置查找下一个头的位置”你错误的根源


你只需要严格按照你头部记录的长度接受数据便可


wateryh 2011-04-09
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 jwybobo2007 的回复:]
不是问题的问题,被演变成了大问题。

你就这么办吧,tcp读数据解析和读文件再解析是一样的道理,因此你可以先测试你的代码通过读文件的方式,这样测试效率高,容易把你的算法理清:

把你的n帧数据保存到文件中,然后你写一个循环读文件,每次读取长度不规则数据,然后解析,验证你的算法代码。这边测试都成功就可以移到你的网络代码中去了。
[/Quote]

好办法
zgc7622 2011-04-09
  • 打赏
  • 举报
回复
TCP协议是流协议。因此你在处理的时候一定要考虑到这一点。
这篇帖子有相关的东西,兴许对你有帮助。
http://www.88dev.com/forum.php?mod=viewthread&tid=89&extra=page%3D1
Wenxy1 2011-04-08
  • 打赏
  • 举报
回复
看经典的书《TCP/IP协议详解》三卷书,还有RFC文档。
xengine-qyt 2011-04-08
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 smwhotjay 的回复:]
我以前可是困惑了1个多月啊.. 现在精通了.. tcp socket 没什么好怕的.
[/Quote]

膜拜大牛 求大牛 教教我协议栈
Eleven 2011-04-07
  • 打赏
  • 举报
回复
根据包长,循环接收后续的数据http://www.vckbase.com/document/viewdoc/?id=1203
vansbluge 2011-04-07
  • 打赏
  • 举报
回复
tcp不是数据流吗 粘什么包?

发送的数据一般不都是头+数据体的结构吗,头是固定长度,头里面有字段指定后面数据体的长度,读完这个长度又开始读头不断循环。 还是说我理解有错?
jwybobo2007 2011-04-07
  • 打赏
  • 举报
回复
比如你的包大小为1024,那你写的测试代码在读文件测试时,每次随机读小于2048的数据进行解析测试,当然简单点的话你就先定义每次读取长度如512,测试完没问题,再测试读1500字节,再测试读4000字节,这样来测试你的算法
gjskxy 2011-04-06
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 jwybobo2007 的回复:]
不是问题的问题,被演变成了大问题。

你就这么办吧,tcp读数据解析和读文件再解析是一样的道理,因此你可以先测试你的代码通过读文件的方式,这样测试效率高,容易把你的算法理清:

把你的n帧数据保存到文件中,然后你写一个循环读文件,每次读取长度不规则数据,然后解析,验证你的算法代码。这边测试都成功就可以移到你的网络代码中去了。
[/Quote]
循环读文件,每次读取长度不规则数据 ......
是说的神马意思,求求耐心多说点啊
gjskxy 2011-04-06
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 hurryboylqs 的回复:]
要用while方式循环读取TCP数据,直到读完一包自定义长度的数据包,再解析
[/Quote]
关键是我的每个包 长度不一样,你知道怎么处理好吗?
求求一定回啊
hurryboylqs 2011-03-31
  • 打赏
  • 举报
回复
要用while方式循环读取TCP数据,直到读完一包自定义长度的数据包,再解析
gjskxy 2011-03-30
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 smwhotjay 的回复:]
我以前可是困惑了1个多月啊.. 现在精通了.. tcp socket 没什么好怕的.
[/Quote]

能分享点经验吗
jwybobo2007 2011-03-29
  • 打赏
  • 举报
回复
不是问题的问题,被演变成了大问题。

你就这么办吧,tcp读数据解析和读文件再解析是一样的道理,因此你可以先测试你的代码通过读文件的方式,这样测试效率高,容易把你的算法理清:

把你的n帧数据保存到文件中,然后你写一个循环读文件,每次读取长度不规则数据,然后解析,验证你的算法代码。这边测试都成功就可以移到你的网络代码中去了。
tompaz 2011-03-29
  • 打赏
  • 举报
回复
tcp怎么可能有粘包?
文件读写有粘包么?
smwhotjay 2011-03-29
  • 打赏
  • 举报
回复
我以前可是困惑了1个多月啊.. 现在精通了.. tcp socket 没什么好怕的.
gjskxy 2011-03-29
  • 打赏
  • 举报
回复
case UNFRAME_STATE_INFO_ENUM:
{
// 获取消息体还未接收的长度
UINT32 unLeftLen = OM_GET_RX_LEFT_LEN;

// 消息存放缓冲区已经有的内容长度
UINT32 unUsedLen = OM_GET_MBUF_USEDLEN;

if ( unTempDataLen > unLeftLen )
{
// 表明是条完整消息
PRINT_LOG("domsg","unTempDataLen > unLeftLen"," Line:%ld" , __LINE__);
if ( 0x9F == pTempData[unLeftLen + 1] )
{
PRINT_LOG("domsg","0x9F == pTempData[unLeftLen + 1]"," Line:%ld" , __LINE__);
memcpy( pMsgBuf + unUsedLen, pTempData, unLeftLen );

// 一条完整的消息已经剥离完成,调用或者发送给上层接口处理
// pMsgBuf对应的内存也要到上层去释放,避免重复的copy操作
/*if (NULL != m_pMsgReport)
{
m_pMsgReport->OMTProbeMsgProcess( (char*)pMsgBuf );
}*/
if (NULL != m_pUe)
{
PRINT_LOG("domsg","PostMsgToUE"," Line:%ld" , __LINE__);
m_pUe->PostMsgToUE(pMsgBuf);
}


// 清空解帧结构变量,准备解一条新的消息
CLEAR_UNFRAME_STATE_ST;
ucUnFrameState = UNFRAME_STATE_HEAD_ENUM;

// 调整接收缓冲区的指针以及剩余内容的长度
pTempData += unLeftLen;
unTempDataLen -= unLeftLen;
}
// 消息有问题
else
{

PRINT_LOG("domsg","消息有问题"," Line:%ld" , __LINE__);

// 重新一块内存,简化处理
pTempCvBuff = (UINT8*) malloc( unTempDataLen + unUsedLen);

if ( !pTempCvBuff )
{
return FALSE;
}

// 初始化分配的内存
memset( pTempCvBuff, 0, unTempDataLen + unUsedLen );

if ( pMsgBuf )
{
memcpy( pTempCvBuff, pMsgBuf, unUsedLen );
memcpy( pTempCvBuff + unUsedLen, pTempData, unTempDataLen );
OM_FREE_RX_MBUFF;
}

// 清空解帧结构变量,准备解一条新的消息
CLEAR_UNFRAME_STATE_ST;
ucUnFrameState = UNFRAME_STATE_HEAD_ENUM;

pTempData = pTempCvBuff;
unTempDataLen += unUsedLen;
}
}
// socket缓冲区中的最后一条消息
else if ( unTempDataLen == unLeftLen )
{

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧