100元话费+500莫元咨询TCP 黏包服务器怎么处理的问题

2020-01-01 17:38发布

本帖最后由 lindabell 于 2017-1-12 16:42 编辑

事情是这样的,我做了一台设备可以通过app控制,也可以上报温湿度等信息的;使用透传的WIFI模块。
设备从关机到开机会发生很多状态变化,都会上传这些状态;通过串口发送到WIFI模块,然后到服务器。
在服务器接收那边就会出现黏包的现象,由于黏包服务器处理起来非常耗时,应该是3~4s的数据到了数据库看居然花了26s左右。

另外我数据的格式是这样的 55AA+MAC+len+CRC8,黏包就是多包数据被TCP封成一个包了。

希望做个服务器 (要专业做服务器的,不是专业的意见不接受)的坛友,给个意见这样的黏包服务器能不能处理,怎样处理?

注:我是做单片机软件的对服务器一点不懂,但是我需要的是专业的回答,另外回答的不错的;可能还会付费咨询更加详细的,报酬方面可谈。


修改:增加到200元话费,高手希望提示一下
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
88条回答
飞剑
1楼-- · 2020-01-05 09:49
以前碰到过,有办法解决。
由于粘包不可避免,所以可以从协议上下手,使用包头或者包尾来从粘包数据中区分每一包的数据。但是不做特殊处理,粘包后包头包尾可能会和数据混淆,所以可以按照下面的方法来做,将包头包尾从数据中区分开来。
比如发送[11,bb,cc]的数据过去,可以将11这个十六进制拆分成两个字节[31,31],在服务器端再进行解析,31也就是1的ascii码。
对于所有数据来说,都可以是十六进制的,十六进制的字符范围也就是0-9,a-f,比如f0,12,ff,00这些,都可以拆分成两个字节。拆分之后,他们的范围就是30-39(0-9),61-66(a-f),而不在这些范围之内的就可以用作包头包尾了。
那到了这里就简单了,只要看到特定的包头(例如60),那么就认为后面的是新一包的数据,直到再碰到下一个包头,服务端只要用这个规则对数据进行解析即可,例如 60,31,32,61,66(包头,12,af)。
当然,11不仅仅可以拆成[31,31],也可以拆成[01,01],fa也可以拆成[0f,0a],也就是不按照ascii码来拆,那么所有数据范围就是00-0f,除了这些以外的都可以做包头包尾。
fchen2
2楼-- · 2020-01-05 14:58
 精彩回答 2  元偷偷看……
gongxd
3楼-- · 2020-01-05 15:54
很简单,tcp数据包每一个条第一个字节就是后面的长度,完成第一个包,再循环即可,tcp可靠流式传输
gongxd
4楼-- · 2020-01-05 15:55
很简单,tcp数据包每一个条第一个字节就是后面的长度,完成第一个包,再循环即可,tcp可靠流式传输
tribear
5楼-- · 2020-01-05 20:38
本帖最后由 tribear 于 2017-1-12 19:58 编辑

TCP粘包一般是2个或者以上的TCP包粘结在一起,一般不会出现数据帧不完整的情况所以,可以用递归调用的方法处理TCP的粘包问题.
比如说你封装一个解析TCP数据帧的函数DecodeTCPFrame(uint8_t *TCPData, int TCPLength)  (TCPData[]为缓冲数组,TCPLength为TCP包的字节),
通过对比你自定义协议帧中的Len长度和TCP的包长度就能判断是不是有粘包的情况,
如果有粘包的情况就再递归调用一遍DecodeTCPFrame(&TCPData[第二帧起始字节下标],TCPLength - 上一个帧的完整长度).
一直对比到TCPLength 和数据帧Len符合时跳出DecodeTCPFrame函数.

把上面解析到的数据帧存到一个结构体数组里,搞定~
zyw19987
6楼-- · 2020-01-06 00:21
怀疑不是模块自动帮忙组包上传造成的,仔细看看模块手册是不是有包间隔时间之类的参数。

一周热门 更多>