关于我正在制作的应用程序中数据包的解释,我有一个相当复杂的问题。主机应用程序向具有以下结构的客户端应用程序发送数据包:
[头10个字节][所选可变字节长度客户端的peerID][空字节][可变字节长度的客户端的peer ID][空白字节][4个字节的整数][可变比特长度客户端的peerID][空闲字节][四个字节的复数]
以下是在这种结构下生成的示例数据包:
434e4c50 00000000006a3134 31303837 34393634 00313233 38313638 35383900 000003e8 31343130 38373439 36340000 0003e8
转换后看起来是这样的:
CNLP电话:1410874964 1238168589 141087496 4
“CNLP j”是10个字节的数据包标头。“1410874964”是所选客户端的peerID。“1238168589”是另一个客户端的peerID。“”的int值为1000。“1410874964”是另一个客户端(在本例中为所选客户端)的peerID。“”的int值也为1000。基本上,在这个数据包中,我正在传达两件事——选择的客户端是谁以及与每个客户端相关的int值。
我的问题存在于口译方面(客户方面)。为了解释这种特定类型的数据包,我使用以下方法:
+ (NSMutableDictionary *)infoFromData:(NSData *)data atOffset:(size_t) offset
{
size_t count;
NSMutableDictionary *info = [NSMutableDictionary dictionaryWithCapacity:8];
while (offset < [data length])
{
NSString *peerID = [data cnl_stringAtOffset:offset bytesRead:&count];
offset += count;
NSNumber *number = [NSNumber numberWithInteger:[data cnl_int32AtOffset:offset]];
offset += 4;
[info setObject:number forKey:peerID];
}
return info;
}
通常,这些数据包中的每个数据包的范围在49到51个字节之间。“偏移量”在前面的方法中设置,以反映数据包标头后的字节数加上所选播放器后的空字节(在上述数据包的情况下,为21)。“count”被初始化为值1。在该特定示例的情况下,长度为51。以下方法传递了上述参数:
- (NSString *)cnl_stringAtOffset:(size_t)offset bytesRead:(size_t *)amount
{
const char *charBytes = (const char *)[self bytes];
NSString *string = [NSString stringWithUTF8String:charBytes + offset];
*amount = strlen(charBytes + offset) + 1;
return string;
}
该方法应该读取数据包中的可变长度字符串,将偏移量设置为peerID字符串后面的空字节填充后的字节,并返回读取的字符串。然后将“amount”设置为该方法为字符串读取的字节数(返回到第一个方法后,这将成为count的新值)。然后,“offset”和“count”被加在一起,成为新的“偏移量”——数据包的int部分的解释将从这里开始。将上述参数传递给以下方法:
- (int)cnl_int32AtOffset:(size_t)offset
{
const int *intBytes = (const int *)[self bytes];
return ntohl(intBytes[offset / 4]);
}
此方法旨在返回在数据包的当前偏移值处读取的32位(4字节)int值。我认为,当偏移量是一个不能被4整除的数字时,这种方法就存在问题。在这种情况下,第一个int值1000被正确解释,32在while循环的第一次迭代期间被返回作为偏移量。然而,在第二次迭代过程中,解释的int值为909377536(从读取数据包中的字节36340000而不是字节000003E8中获得)。这可能是由于该迭代过程中的偏移量被设置为47(不可被4整除)。在解释了上述类别中的32位int之后,在第一种方法中,将4添加到偏移量,以说明4字节(32位int)。如果我关于偏移量不可被零整除的直觉是正确的,那么任何解决这个问题的建议都将不胜感激。很长一段时间以来,我一直在寻找解决这个问题的方法,也许新的眼光会有所帮助。谢谢你的帮助!!!