关于我正在制作的应用程序中数据包的解释,我有一个相当复杂的问题。主机应用程序使用以下结构向客户端应用程序发送数据包:
[10 字节的头][选定的可变字节长度客户端的peerID][空字节][可变字节长度客户端的peerID][空字节][4 字节的int][可变字节长度客户端的peerID][空字节][int of 4 bytes]
以下是在此结构下生成的示例数据包:
434e4c50 00000000 006a3134 31303837 34393634 00313233 38313638 35383900 000003e8 31343130 38373439 36340000 0003e8
转换后看起来像这样:
CNLP j1410874964 1238168589 Ë1410874964 Ë
“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 个字节之间。“offset”在之前的方法中设置,以反映包头之后的字节数加上所选播放器之后的空字节(在上述数据包的情况下,为 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 字符串后面的空字节填充后的字节,并返回读取的字符串。然后将“数量”设置为该方法读取的字符串的字节数(这将成为返回第一个方法后的新计数值)。然后将“offset”和“count”加在一起成为新的“offset”——从这里开始解释数据包的 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 被正确解释,并且在 while 的第一次迭代期间将 32 作为偏移量返回环形。但是,在第二次迭代期间,解释的 int 值是 909377536(通过读取数据包中的字节 36340000 而不是字节 000003E8 获得)这可能是由于此迭代期间的偏移量设置为 47(不能被 4 整除) . 在解释了上述类别中的 32 位 int 之后,在第一种方法中将偏移量添加 4 以占 4 字节(32 位 int)。如果我对不能被零整除的偏移量的直觉是正确的,非常感谢任何解决此问题的建议。很长一段时间以来,我一直在寻找解决这个问题的方法,也许新鲜的眼睛可能会有所帮助。谢谢你的帮助!!!