さて、私は一日中このバグに直面していて、根本的な問題に絞り込んだと思います。
バックグラウンド:
私は自分のバージョンを作成し、iOS 5でBluetooth経由のBonjourを許可する必要があるアプリに取り組んでいNSNetService
ますNSNetServiceBrowser
。このプロジェクトを開始する前は、ネットワークプログラミングについて何も知らなかったので、これは素晴らしい冒険でした。私はさまざまなサンプルプロジェクトや古典的なUnixネットワークプログラミングの教科書から多くのことを学びました。私の実装は、主にAppleのDNSSDObjects
サンプルプロジェクトに基づいています。サービスが解決されたら、実際にデバイス間を接続するコードを追加しました。anNSInputStream
とanNSOutputStream
はで達成されCFStreamCreatePairWithSocketToHost( ... )
ます。
問題:
この接続を介してデータを送信しようとしています。データは、整数、少数NSStrings
、およびでNSData
アーカイブされたオブジェクトで構成されNSKeyedArchiver
ます。のサイズNSData
は約150kbなので、メッセージ全体のサイズは約160kbです。接続を介してデータを送信した後、アーカイブを解除しようとすると、次の例外が発生します...
Terminating app due to uncaught exception 'NSInvalidArgumentException',
reason: '*** -[NSKeyedUnarchiver initForReadingWithData:]: incomprehensible archive
さらに調べてみると、受信したデータが約2kbしかないことに気づきました。メッセージが切り捨てられているため、アーカイブが「理解できない」状態になっています。
関連する可能性のあるコード:
接続されているすべてのデバイスにデータを送信する方法
- (void) sendMessageToPeers:(MyMessage *)msg
{
NSEnumerator *e = [self.peers objectEnumerator];
//MyMessage conforms to NSCoding, messageAsData getter calls encodeWithCoder:
NSData *data = msg.messageAsData;
Peer *peer;
while (peer = [e nextObject]) {
if (![peer sendData:data]) {
NSLog(@"Could not send data to peer..");
}
}
}
実際にデータを書き込むPeerクラスのメソッドNSOutputStream
- (BOOL) sendData:(NSData *)data
{
if (self.outputStream.hasSpaceAvailable) {
[self.outputStream write:data.bytes maxLength:data.length];
return YES;
}
else {
NSLog(@"PEER DIDN'T HAVE SPACE!!!");
return NO;
}
}
ストリームイベントを処理する(データを「受信する」)ためのNSStreamDelegateメソッド
このコードのバッファサイズは32768b/ cで、これは私が学んだサンプルコードにあったものです。それは任意ですか?バッファが小さすぎるだけだと思って200000に変更してみましたが、何も変わりませんでした。何が起こっているのかよくわからないと思います。
- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)eventCode
{
switch (eventCode) {
case NSStreamEventHasBytesAvailable: {
NSInteger bytesRead;
uint8_t buffer[32768]; // is this the issue?
// uint8_t buffer[200000]; //this didn't change anything
bytesRead = [self.inputStream read:buffer maxLength:sizeof(buffer)];
if (bytesRead == -1) ...;
else if (bytesRead == 0) ...;
else {
NSData *data = [NSData dataWithBytes:buffer length:bytesRead];
[self didReceiveData:data];
}
} break;
/*omitted code for other events*/
}
}