从iOS发送C ++协议缓冲消息

时间:2013-02-03 19:26:58

标签: ios sockets protocol-buffers akka nsstream

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的方式有问题......任何人都可以发现我的愚蠢错误,因为我和# 39;我确定这里发生了什么。

1 个答案:

答案 0 :(得分:2)

血腥的地狱。我不敢相信我没有看到这一点。在这里的代码行中:

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

我使用值“length”表示要传输的最大字节数。不幸的是,这个价值已经让它的“endian”顺序翻转,准备通过网络传输。我用[rawZombie length]取代了“length”,它就像一个魅力。

:(