【发布时间】:2012-07-11 00:21:18
【问题描述】:
好的,所以我整天都在处理这个错误,我想我已经把它缩小到了根本问题。
背景:
我正在开发一个应用程序,该应用程序要求我编写自己的 NSNetService 和 NSNetServiceBrowser 版本,以便在 iOS 5 中通过蓝牙支持 Bonjour。这是一次伟大的冒险,因为我对网络编程一无所知在我开始这个项目之前。我从各种示例项目和经典的Unix Network Programming 教科书中学到了很多东西。我的实现主要基于 Apple 的 DNSSDObjects 示例项目。一旦解决了服务,我添加了代码以实际建立设备之间的连接。 NSInputStream 和 NSOutputStream 通过 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 方法
此代码中的缓冲区大小是 32768 b/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*/
}
}
【问题讨论】:
-
添加逻辑以实际计算您发送和接收的字节数。我怀疑您只收到第一个缓冲区。您的
didReceiveData方法应该是从多个缓冲区累积数据。
标签: objective-c ios5 network-programming nsstream nscoder