【硬件问题】关于tcp与buffer
发布于 8 年前 作者 Lanseria 4199 次预览 最后一次回复是 7 年前 来自 问答
是这样的,因为要做数据的联调,所以必须tcp之类的通信 可是毕竟硬件传过来的事hex 也就是二进制的数据, 类似下面这中数据,我本想用构造去做,不过因为有些长度是会变的,所以很难处理,如果要按硬件一次一次轮询的去判断,switch实在太多了,求大佬的经验之谈!
53 54 41 54 00 0F 01 00 00 00 00 00 00 BB 01 AA 09 BB 01 00 01 00 00 00 00 00 01 0E CC 33 45 4E 44
53 54 41 54 (STAT)
00 0F (长度)\\\\\\\\\\\\\\\\\\\\\
01 (cmd)
00 00 00 00 00 00 (网关ID)
BB
01 (模块数量)
AA (头)\\\\\\\\\\\\\\\\\\\15
09 (长度)16
BB 17
01 00 (设备类型) 18
01 00 00 00 00 00 (设备ID)20
01 (具体的数据)26
0E (子crc)27
CC (模块数据结束)28
33 CRC(总)
45 4E 44 (END)
8 回复
有木有人 From Noder
首先要自定义协议,解决粘包与分包问题,不然,收到的数据无法解析的
弱弱的问一下,这种自定义TCP通信的话,是不是最起码要有一个长度的说明,比如HTTP中的Content-length,这样客户端这边才知道用多大的Buffer去装
协议头 协议长度 协议体 CRC 除了协议体其他是固定的
使用protobuf 塞到buffer里,然后自己写转换。需要处理粘包,5年前我第一个项目就是这么做的。5年前的代码了,你凑活凑活看吧,
function GameMain(aPort,aCallback){ var mCenterSocket = mNet.createConnection(aPort,‘127.0.0.1’); /** 连接成功 */ mCenterSocket.on(‘connect’, function() { mProcessingLogic.SetSocket(mCenterSocket); mProcessingLogic.EfficacySocket(); mLogger.ConsoleLog("Connected to GateServer at port: " + aPort); });
}
------------------------------------mPackageSystem.js-------------------------------------------- function exPackag(aCallback) { this.mBuffer = new Array();// 缓冲容器 this.mBuffer_len = 0;// 协议长度 this.mData_len_Median = 2;// 协议的长度所占的位数 this.mCallback = aCallback;// 回调函数 }
exPackag.prototype.putData = function(aData) { //mLogger.ConsoleLog("PS putData: " + aData.length); if (this.mBuffer_len == 0) { if (aData.length < this.mData_len_Median) { mLogger.SetDebug(‘包头不全直接忽略’); return; } else { this.mBuffer_len = getIntToByte16(aData) + this.mData_len_Median; } }
};
function getIntToByte16(aRecv) { var targets = (aRecv[0] & 0xff) | ((aRecv[1] << 8) & 0xff00); return targets; }
exports.exPackag = exPackag;
-----------------------------------------------------压缩部分----------------------------------------- //aData是protobuf结构 function serializedServerBag(aData) { aData=JSON.stringify(aData); aData=new Buffer(aData); var tMessageDataLen=aData.length; var tValue=getByteToInt16(tMessageDataLen); var tBuf=Array(); tBuf=tBuf.concat(tValue); for(var index=0; index<aData.length; index++) { tBuf.push(aData[index]); } return tBuf; }
谢谢,我会仔细看的
@beiyio 您好,有个问题想请教下还望您帮忙解答:当解到包后,业务需要对某些包进行处理,是比较耗时的for循环,会使程序阻塞,此时有可能使tcp的传输收到阻塞,而丢失部分数据,要防止这种问题,请问有什么好的办法吗?(发送端的缓存极小,通常阻塞500ms就已经撑满发送端的TCP缓存区,即出现丢包,所以,TCP的重传机制在这种情况也不能生效)
@Lanseria 您好,有个问题想请教下还望您帮忙解答:当解到包后,业务需要对某些包进行处理,是比较耗时的for循环,会使程序阻塞,此时有可能使tcp的传输收到阻塞,而丢失部分数据,要防止这种问题,请问有什么好的办法吗?(发送端的缓存极小,通常阻塞500ms就已经撑满发送端的TCP缓存区,即出现丢包,所以,TCP的重传机制在这种情况也不能生效)