2013-02-03 116 views
1

previous Stack Overflow question中,人们在构建我的Akka套接字服务器时向我展示了我的方式错误方面非常有帮助,现在我实际上有一个Akka套接字客户端,它可以发送具有以下帧的消息:从iOS发送C++协议缓冲区消息

消息长度: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客户端正常工作没有这种额外的任意废话,我假设有什么问题,我怎么写protobuf对象到NSStream ......任何人都可以发现我的愚蠢的错误,因为我确信这就是这里正在发生。

+0

你登录你*发送的消息*的长度作比较? –

+0

所有的长度和字节计数是45 rawZombie长度]是45上的发送(IOS)侧,其与protobuf对象上的ByteSize()方法相同(返回45)。 –

+0

是坏数据的“长度7”部分,那么?此外:大多数时候我看到过这种情况,它或者与发送MemoryStream的后备缓冲区(而不是修剪后的数据),或者搞乱了网络IO。这里是否有这种情况? –

回答

2

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

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

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

:(