2013-02-03 113 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長度]替換了「長度」,它的功能就像一個魅力。

:(