我在从TCP流接收数据包数据时遇到了一些麻烦。我认为这部分是由于不理解服务器响应。
我的代码(目标c):
unsigned type=0;
unsigned bufferFirstByte=0;
unsigned bufferSecondByte=0;
unsigned bufferThirdByte=0;
NSScanner *hexToInt = [NSScanner scannerWithString:[mutableBuffer objectAtIndex:0]];
[hexToInt scanHexInt:&bufferFirstByte];
hexToInt = [NSScanner scannerWithString:[mutableBuffer objectAtIndex:1]];
[hexToInt scanHexInt:&bufferSecondByte];
hexToInt = [NSScanner scannerWithString:[mutableBuffer objectAtIndex:2]];
[hexToInt scanHexInt:&bufferThirdByte];
hexToInt = [NSScanner scannerWithString:[mutableBuffer objectAtIndex:0]];
[hexToInt scanHexInt:&type];
int len = (bufferSecondByte<<8)+bufferSecondByte;
if (![mutableBuffer count]<(3+len)) {
NSArray *payload = [mutableBuffer subarrayWithRange:NSMakeRange(2,([mutableBuffer count] - 2))];
NSLog(@"length %d",len);
[self processReceive:type length:len payload:payload];
}
是从this javascript代码建模的内容:
self.receive = function (itemName, data) {
self.log("Receiving: " + self.toHex(data));
self.ourData += data;
while (self.ourData.length >= 3) {
var type = self.ourData.charCodeAt(0);
var len = (self.ourData.charCodeAt(1) << 8) + self.ourData.charCodeAt(2);
if (self.ourData.length < (3 + len)) { // sanity check: buffer doesn't contain all the data advertised in the packet
break;
}
var payload = self.ourData.substr(3,len);
self.ourData = self.ourData.substr(3 + len);
self.processMessage(type, len, payload); // process payload
}
};
建模的原因是命令融合javascript项目正在与我所在的同一服务器(一个crestron控制器)进行通信。
然而,我永远无法让len工作起来,我认为这就是造成我的问题。在查看示例数据包时(05:00:06:00:00:03:00:52:00),即使数据部分只有9字节,len也会等于1280(参见上面的数学运算)。
目前我的代码可以使用,但它会遗漏某些数据。这是因为TCP执行的流式传输(某些数据包被连接而其他数据包被分段)。但是,如果不知道数据段大小,我无法解决问题,我相信答案就是len
变量。但我没有看到如何正确实施它。
我的问题归结为此。如何从这个len
变量确定数据段的大小,或者将我的接收方法控制为一次只有一个数据段(由于我的研究是不可能的,因为TCP是一个流)? /强>
我觉得会有问题,所以我会尝试在这里回答其中一些问题。
一个。你如何提出1280:看方法((self.ourData.charCodeAt(1) << 8) + self.ourData.charCodeAt(2);)
中的数学(5 <&lt; 8&lt;&lt; 8)+ 0 = 1280d
B中。为什么使用不同的索引:
您会注意到哪些数据的索引在哪里(payload, len, type
)。这仅仅是因为它们将有效载荷/数据字节作为字符串而myn是一个数组。最后它是被引用的相同数据
答案 0 :(得分:2)
使用以下逻辑:
1)你有足够的字节来确定长度吗?如果没有,请再接收一些字节,然后重试。
2)你有足够的字节来拥有一个完整的单位吗?如果没有,请再接收一些字节,然后重试。
3)使用步骤1中的解码长度提取一个完整单元并进行处理。
4)如果我们没有剩余的字节,我们就完成了。
5)返回步骤1处理剩余的字节。
答案 1 :(得分:0)
好的,所以我从(this group)获得了一些帮助,如果没有登录该组,您可能无法看到。在任何情况下都有一个3字节的标题。所以我的len是6而不是像我想的那样1280实际上是9为标题添加3。这让我得到了我所追求的价值(9),因为数据段是9字节。
感谢大卫提出的建议,以及一些良好的基础知识。