从TCP流中解析出数据段

时间:2011-12-12 21:31:20

标签: javascript objective-c ipad

我在从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是一个数组。最后它是被引用的相同数据

2 个答案:

答案 0 :(得分:2)

使用以下逻辑:

1)你有足够的字节来确定长度吗?如果没有,请再接收一些字节,然后重试。

2)你有足够的字节来拥有一个完整的单位吗?如果没有,请再接收一些字节,然后重试。

3)使用步骤1中的解码长度提取一个完整单元并进行处理。

4)如果我们没有剩余的字节,我们就完成了。

5)返回步骤1处理剩余的字节。

答案 1 :(得分:0)

好的,所以我从(this group)获得了一些帮助,如果没有登录该组,您可能无法看到。在任何情况下都有一个3字节的标题。所以我的len是6而不是像我想的那样1280实际上是9为标题添加3。这让我得到了我所追求的价值(9),因为数据段是9字节。

感谢大卫提出的建议,以及一些良好的基础知识。