TCP粘包和半包的处理方法
先把处理的方法的代码放这里:
解析数据帧的代码:
bool CSocket::findData(byte* buff, int& len)
{ for (int i = 0; i <= len - 4; i++)
{
int dataLen;
if(buff[i] == 0xAA && buff[i + 1] == 0xBB)
{
short slen;
slen = (short)(byte(buff[i+3]));
slen |=(short)((short)(byte(buff[i+2])) << 8);
dataLen = slen;
if(slen < 0)
return false; if(i+4 +dataLen + 4 <= len)
{
if(buff[i + 4 + dataLen] == 0x0DD && buff[i + 4 + dataLen + 1] == 0xEE && buff[i + 4 + dataLen + 2] == 0xDD && buff[i + 4 + dataLen + 3] == 0xEE)
{
MsgType type;
memcpy(&type, buff + i + 4 , sizeof(type)); if(type == ID_LASER)
{}
else if(type == ID_PATH)
{}
else if(type == ID_POSE)
{}
len = len - i - 4 - dataLen - 4;
if( len > 0)
{
memcpy(swapBuff, buff + i + 4 + dataLen + 4, len);
memcpy(buff, swapBuff, len);
}
return true;
}
else
{
len = len - i -4;
if(len > 0)
{
memcpy(swapBuff, buff + i + 4, len);
memcpy(buff, swapBuff, len);
return false;
}
}
}//if
else if(i != 0)
{
len = len - i;
memcpy(swapBuff, buff + i, len);
memcpy(buff, swapBuff, len);
return false;
}
}//if
}//for return false;
}//end function
接收数据帧的代码:
void CSocket::receiveData()
{
ROS_INFO("Receive Thread Start..."); int len =0;
int revDateCount = 0;
while(bRunning)
{
if(!connected)
{
ROS_INFO("Restarting connection...");
ErroFunc(_T("连接中断,尝试重新连接...")); if(serverSocket > 0)
{
closesocket(serverSocket);
serverSocket = -1;
} if(clientSocket > 0)
{
closesocket(clientSocket);
clientSocket = -1;
} bool re;
if(bServer)
re = startServer();
else
re = connectServer();
if(!re)
continue;
revDateCount = 0;
MsgFunc(_T("连接到机器人!"));
} int re = selectSocket(clientSocket, 500);
if(re < 0)
{
ROS_ERROR("Receive Thread Select Error!");
connected = false;
continue;
}
else if(re == 0)
continue;
else
{
len = recv(clientSocket, (char*)recvBuffer, MAX_BUFFER_LEN, 0);
if(len > 0)
{
if(revDateCount + len < MAX_BUFFER_LEN)
{
memcpy((void*)(buff + revDateCount), (void*)recvBuffer, len);
revDateCount += len;
}
else
{
memcpy((void*)buff, (void*)recvBuffer, len);
revDateCount = len;
} while(findData(buff, revDateCount))
{
ROS_INFO("Receive data!");
}
}
else
{
ROS_ERROR("Receive Data Error!");
connected = false;
goto __reconnect__;
}
}
__reconnect__:;
}
ROS_INFO("Receive Thread Stop.");
}
TCP粘包和半包的处理方法的更多相关文章
- 关于TCP封包、粘包、半包
关于Tcp封包 很多朋友已经对此作了不少研究,也花费不少心血编写了实现代码和blog文档.当然也充斥着一些各式的评论,自己看了一下,总结一些心得. 首先我们学习一下这些朋友的心得,他们是: http: ...
- socket编程 TCP 粘包和半包 的问题及解决办法
一般在socket处理大数据量传输的时候会产生粘包和半包问题,有的时候tcp为了提高效率会缓冲N个包后再一起发出去,这个与缓存和网络有关系. 粘包 为x.5个包 半包 为0.5个包 由于网络原因 一次 ...
- TCP的粘包、半包和Netty的处理
参考文献:极客时间傅健老师的<Netty源码剖析与实战>Talk is cheap.show me the code! 什么是粘包和半包 在客户端发送数据时,实际是把数据写入到了TCP发送 ...
- 详说tcp粘包和半包
tcp服务端和客户端建立连接后会长时间维持这个连接,用于互相传递数据,tcp是以流的方式传输数据的,就像一个水管里的水一样,从一头不断的流向另一头. 理想情况下,发送的数据包都是独立的, 现实要复杂一 ...
- Netty - 粘包和半包(上)
在网络传输中,粘包和半包应该是最常出现的问题,作为 Java 中最常使用的 NIO 网络框架 Netty,它又是如何解决的呢?今天就让我们来看看. 定义 TCP 传输中,客户端发送数据,实际是把数据写 ...
- C#下利用封包、拆包原理解决Socket粘包、半包问题(新手篇)
介于网络上充斥着大量的含糊其辞的Socket初级教程,扰乱着新手的学习方向,我来扼要的教一下新手应该怎么合理的处理Socket这个玩意儿. 一般来说,教你C#下Socket编程的老师,很少会教你如何解 ...
- Netty - 粘包和半包(下)
上一篇介绍了粘包和半包及其通用的解决方案,今天重点来看一下 Netty 是如何实现封装成帧(Framing)方案的. 解码核心流程 之前介绍过三种解码器FixedLengthFrameDecoder. ...
- TCP的组包、半包、粘包与分包
一.概念 1)组包.简单的说就是tcp协议把过大的数据包分成了几个小的包传输,接收方要把同一组的数据包重新组合成一个完整的数据包. 2)半包.指接受方没有接受到一个完整的包,只接受了部分,这种情况主要 ...
- c# socket 解决粘包,半包
处理原理: 半包:即一条消息底层分几次发送,先有个头包读取整条消息的长度,当不满足长度时,将消息临时缓存起来,直到满足长度再解码 粘包:两条完整/不完整消息粘在一起,一般是解码完上一条消息,然后再判断 ...
随机推荐
- MYSQL 执行计划
Explain语法 EXPLAIN SELECT …… 变体: 1. EXPLAIN EXTENDED SELECT …… 将执行计划“反编译”成SELECT语句,运行SHOW WARNINGS 可得 ...
- RedHat升级内核成功
升级前 uname -aLinux localhost.localdomain 2.6.18-194.el5 #1 SMP Tue Mar 16 21:52:39 EDT 2010 x86_64 x8 ...
- HDU1069:Monkey and Banana(DP+贪心)
Problem Description A group of researchers are designing an experiment to test the IQ of a monkey. T ...
- ZOJ 2562 More Divisors(高合成数)
ZOJ 2562 More Divisors(高合成数) ACM 题目地址:ZOJ 2562 More Divisors 题意: 求小于n的最大的高合成数,高合成数指一类整数,不论什么比它小的自然数 ...
- 在unity中用鼠标实现在场景中拖动物体,用鼠标滚轮实现缩放
在场景中添加一个Plan,Camera,Directional Light,Cube.添加两个脚本scrollerScirpt(挂在Camera),CubeDragScript(挂在Cube上). 1 ...
- HDU OJ 5437 Alisha’s Party 2015online A
题目:click here 题意: 邀请k个朋友,每个朋友带有礼物价值不一,m次开门,每次开门让一定人数p(如果门外人数少于p,全都进去)进来,当最后所有人都到了还会再开一次门,让还没进来的人进来,每 ...
- Oracle Enterprise Manager 11g 输入用户名和口令 点击“登录”按键后没反应,也不报错,是什么原因?
在tnsnames.ora文件中检查设置好像没什么问题,用sqlplus也可以正常操作orcl 问题找到了,其实可简单,https://localhost:1158/em/console/logon/ ...
- 经典阅读-《Effective C++》Item1:视C++为一个联邦语言
C++已经是个多重范型编程语言(multiparadigm programming language),一个同时支持过程形式(procedural).面向对象形式(object-oriented).泛 ...
- python自学笔记(十一)关于函数及书写格式
1.函数是抽象的第一步 1.1 有关高压锅 1.2 函数是抽象出来的结构,是总结,是方法 1.3 多用函数 2.如何定义函数 2.1 def是关键词, ...
- Linux 下的 fork()【转载】
[原文地址]http://blog.csdn.net/hikaliv/article/details/4276758 [cpp] view plaincopy for( i = 0; i < ...