2015-11-13 4 views
7

私はBonjourで目的cのtcpサーバ/クライアントの開発に問題があります。iOS NSStream tcpサーバクライアントが通信できません

私はストリームを正しく開き、handleEvent関数を使ってデータを送受信します。しかし、データを送受信するための適切な方法は何か分かりません。私はこの素晴らしい記事を読む:Correct way to send data through a socket with NSOutputStream だから私は、データを送信するために、パケットキューに入れられたシステムを使用します。

switch(eventCode) { 

    case NSStreamEventOpenCompleted: { 
     NSLog(@"Complete"); 

    } break; 

    case NSStreamEventHasSpaceAvailable: { 
     if (stream == _outputStream) 
      [self _sendData]; 
    } break; 

...

- (void)_sendData { 
flag_canSendDirectly = NO; 
NSData *data = [_dataWriteQueue lastObject]; 
if (data == nil) { 
    flag_canSendDirectly = YES; 
    return; 
} 
uint8_t *readBytes = (uint8_t *)[data bytes]; 
readBytes += currentDataOffset; 
NSUInteger dataLength = [data length]; 
NSUInteger lengthOfDataToWrite = (dataLength - currentDataOffset >= 1024) ? 1024 : (dataLength - currentDataOffset); 
NSInteger bytesWritten = [_outputStream write:readBytes maxLength:lengthOfDataToWrite]; 
currentDataOffset += bytesWritten; 
if (bytesWritten > 0) { 
    self.currentDataOffset += bytesWritten; 
    if (self.currentDataOffset == dataLength) { 
     [self.dataWriteQueue removeLastObject]; 
     self.currentDataOffset = 0; 
    } 
} 

}

。だから、基本的に私は多くのパケットで別々のデータを送信します。しかし、クライアント側でデータを再構築する方法はわかりません。そして、私はNSStreamEventHasBytesAvailableイベントを正しく理解していないと思います。ここで私は多くのパケットを送信するので、クライアント側でこのイベントは一度だけコールです。バッファからデータを再構築すると、データが破損しているように見えます。私は本当に誰かがこのすべてを明確にすることができれば、本当に感謝します。ドキュメントはこの時点で本当に明確ではありません。インスタンス変数とプロパティ - - 同じ目的のために

 case NSStreamEventHasBytesAvailable: { 
     if (stream == _inputStream) 
     { 
      //read data 
      uint8_t buffer[1024]; 
      int len; 
      while ([_inputStream hasBytesAvailable]) 
      { 
       len = [_inputStream read:buffer maxLength:sizeof(buffer)]; 
       if (len > 0) 
       { 
        NSString *output = [[NSString alloc] initWithBytes:buffer length:len encoding:NSUTF8StringEncoding]; 
        //NSData *theData = [[NSData alloc] initWithBytes:buffer length:len]; 
        UnitySendMessage("AppleBonjour_UnityNetworkManager(Clone)", "OnLocalClientReceiveMessageFromServer", [output cStringUsingEncoding:NSUTF8StringEncoding]); 
       } 
      } 
     } 
+0

簡単なテストを試しましたか?単一の短い文字列を送信します。これを行うと、変数 "出力"には何が含まれますか? fwiw;各送信に利用可能なバイトの呼び出しが1つである必要はありません。時間内に到着すれば結合され、1つの読み取りはそれらをすべて取得します。このテストを試して、あなたが得るものを教えてください。 –

+0

ああ、もう一つ忘れました。 telnetのような単純なtcpプログラムで受信機をテストすることができます。ポートに接続してテキストを入力するだけです。受信者コードが動作している場合は、テキストを直接取得する必要があります。 –

+0

わかりやすい文字列です。したがって、バッファよりも大きな文字列を送信すると、NSStreamEventHasBytesAvailableが呼び出されるたびにその文字列を再構築するだけで済みます。しかし、文字列が完全に送信されたときにどうすれば通知を受け取ることができますか? – thegrandwaazoo

答えて

3

あなたが2つの変数をcurrentDataOffset使用することを、と思われます。実際に両方が必要な場合は、0currentDataOffsetに設定する必要があります。しかし、私は断片が次のようになるはずだと思います:

readBytes += currentDataOffset; 
NSUInteger dataLength = [data length]; 
NSUInteger lengthOfDataToWrite = MIN(dataLength - currentDataOffset, 1024); 
NSInteger bytesWritten = [_outputStream write:readBytes maxLength:lengthOfDataToWrite]; 
if (bytesWritten > 0) { 
    currentDataOffset += bytesWritten; 
    if (currentDataOffset == dataLength) { 
     [self.dataWriteQueue removeLastObject]; 
     currentDataOffset = 0; 
    } 
}