【问题标题】:Sending C++ Protocol Buffer Messages from iOS从 iOS 发送 C++ 协议缓冲区消息
【发布时间】:2013-02-04 04:25:46
【问题描述】:

previous Stack Overflow question 中,人们在构建我的 Akka 套接字服务器时向我展示了我的错误,实际上我现在有一个 Akka 套接字客户端,它可以使用以下框架发送消息:

消息长度:4字节 消息类型:4字节 消息负载:(长度)字节

这是我用来发送消息的 iOS 代码:

 NSInputStream *inputStream;
    NSOutputStream *outputStream;

    CFReadStreamRef readStream;
    CFWriteStreamRef writeStream;
    CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)@"localhost", 9999, &readStream, &writeStream);
    inputStream = (__bridge_transfer NSInputStream *)readStream;
    outputStream = (__bridge_transfer NSOutputStream *)writeStream;

    [inputStream setDelegate:self];
    [outputStream setDelegate:self];

    [inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    [outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

   // [inputStream open];
    [outputStream open];
    NSLog(@"NSData raw zombie is %d bytes.", [rawZombie length]);
    uint32_t length = (uint32_t)htonl([rawZombie length]);
    uint32_t messageType = (uint32_t)htonl(1);        

    NSLog(@"Protobuf byte size %d", zombieSighting->ByteSize());

    [outputStream write:(uint8_t *)&length maxLength:4];
    [outputStream write:(uint8_t *)&messageType maxLength:4];
    [outputStream write:(uint8_t *)[rawZombie bytes] maxLength:length];

    [outputStream close];

'rawZombie'变量(NSData *)来自以下方法:

- (NSData *)getDataForZombie:(kotancode::ZombieSighting *)zombie {
    std::string ps = zombie->SerializeAsString();
    NSLog(@"raw zombie string:\n[%s]", ps.c_str());
    return [NSData dataWithBytes:ps.c_str() length:ps.size()];
}

我看到的症状是我收到了由 iOS 发送的消息,它的长度是正确的,消息类型 (1) 也是正确的,而且正文很好。使用 Scala protobufs 的 Akka 服务器对消息进行反序列化,并完美地打印出消息上的所有值。问题是,在我收到该消息后,Akka 服务器立即认为它收到了另一条消息(显然,更多数据进入了流中)。每次运行iOS应用最后的数据都不一样。

例如,以下是来自两个连续消息接收的一些跟踪输出:

received message of length 45 and type 1
name:Kevin
lat: 41.007
long: 21.007
desc:This is a zombie
zombie type:FAST
received message of length 7 and type 4
received message of length 45 and type 1
name:Kevin
lat: 41.007
long: 21.007
desc:This is a zombie
zombie type:FAST
received message of length 164 and type 1544487554

所以你可以看到,在 Akka 服务器收到正确的消息数据后,它也收到了一些随机的任意废话。鉴于我的 Akka 客户端可以正常工作而没有这种额外的任意废话,我假设我将 protobuf 对象写入 NSStream 的方式有问题...任何人都可以发现我的愚蠢错误,因为我确信那是什么正在这里发生。

【问题讨论】:

  • 您是否记录了您发送的消息的长度以进行比较?
  • 所有长度和字节数都是45。[rawZombie length]在发送端(iOS)是45,和protobuf对象的ByteSize()方法一样(返回45) .
  • 是坏数据的“长度7”部分,那么呢?另外:大多数时候我都看到过这种情况,它要么与人们发送 MemoryStream 的后备缓冲区(而不是修剪后的数据)有关,要么与网络 IO 混乱有关。这里有没有可能也是这种情况?
  • 长度 7 是坏数据的一部分……它只是意味着在合法的 protobuf 消息之后的 4 个字节中有一个数字 7。我做了一点检查,NSStream“write”方法返回写入流的字节数。就我而言,它写了 653276 个字节。显然这就是多余的废话的来源,但我不知道 - 为什么 - 这个方法写了那么多,尤其是当我告诉它最大长度为 45 时。

标签: ios sockets protocol-buffers akka nsstream


【解决方案1】:

该死的。我不敢相信我没有看到这个。在这里的代码行中:

[outputStream write:(uint8_t *)[rawZombie bytes] maxLength:length]

我使用值“长度”作为要传输的最大字节数。不幸的是,该值已经翻转了它的“endian”顺序,以准备通过网络传输。我用 [rawZombie length] 替换了“长度”,它就像一个魅力。

:(

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-20
    • 2013-09-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多