Objective c hasbytes可以提前完成
我正在将JSON从我的服务器发送到我的cocoa应用程序 cocoa应用程序接收如下数据:Objective c hasbytes可以提前完成,objective-c,json,sockets,cocoa,nsstream,Objective C,Json,Sockets,Cocoa,Nsstream,我正在将JSON从我的服务器发送到我的cocoa应用程序 cocoa应用程序接收如下数据: case NSStreamEventHasBytesAvailable: NSLog(@"begin"); if (theStream == inputStream) { int len; uint8_t buffer[4096]; NSString* incoming_message = @""; while ([input
case NSStreamEventHasBytesAvailable:
NSLog(@"begin");
if (theStream == inputStream) {
int len;
uint8_t buffer[4096];
NSString* incoming_message = @"";
while ([inputStream hasBytesAvailable]) {
len = (int)[inputStream read:buffer maxLength:sizeof(buffer)];
NSLog(@"\nThe length is -- %d\n",len);
if (len > 0) {
NSString *mess = [[NSString alloc] initWithBytes:buffer length:len encoding:NSASCIIStringEncoding];
if(mess != nil){
incoming_message = [NSString stringWithFormat:@"%@%@",incoming_message,mess];
}
}
}
NSLog(@"%@",incoming_message);
// handle icoming message
[self handleIncomingNotification:incoming_message];
}
NSLog(@"end");
break;
问题是,如果数据开始大于500个字符,它会分成两部分(分别调用begin
和end
日志两次),因此handleIncomingNotification:
无法正常工作,因为它传递了一半的JSON
当我记录len
时,我得到了很多1448
,有时是1479
,然后是4096
所以显然,hasBytesAvailable
并没有像它应该的那样工作
我尝试过改变缓冲区,但没有什么区别
请帮我想个办法解决这个问题。我很惊讶这不是一个简单的谷歌
根据xaphod的答案编辑 我最终做了以下几点:
case NSStreamEventHasBytesAvailable:
NSLog(@"begin");
if (theStream == inputStream) {
int len;
uint8_t buffer[1024];
NSString* incoming_message = @"";
while ([inputStream hasBytesAvailable]) {
len = (int)[inputStream read:buffer maxLength:sizeof(buffer)];
if (len > 0) {
NSString *mess = [[NSString alloc] initWithBytes:buffer length:len encoding:NSASCIIStringEncoding];
incoming_message = [NSString stringWithFormat:@"%@%@",incoming_message,mess];
}
}
[self handleStreamMessage:incoming_message];
}
NSLog(@"end");
break;
handleStreamMessage:
这似乎是一个可怕的黑客攻击。NSStream网络流不是这样工作的。如果您发送X字节,接收器将收到N倍于某个数量的数据,总数(最终)将是X。N可能是1、7或42-取决于多个因素 您需要做的是在JSON出现时对其进行解析,并确定何时接收到足够有意义的JSON。查看YAJLParser,我使用它来实现twitterapi。让我给你一个链接
。。我的叉子在这里:我认为它可以按预期工作,您可能应该按照手册操作:。在传递数据/json之前,积累数据并等待
nsstreamventendecountered
further@Andy谢谢,但是当您关闭流时,nsstream不会被反击。在发送消息后,我不会执行此操作。根据文档当NSInputStream对象到达流的末尾时,它会向代理发送一个NSStreamEndended
。这就是流式传输的思想,即增量读取数据。单次读取是可能的,但我认为您应该接收到nsstreamventhasbytesavailable
,直到您使用整个流,然后nsstreamventendecountered
应该到达。你们可以在操场上自己测试。别忘了正确处理错误和清理流。我只是想知道,你们是通过套接字(又名meteor?)连续传输JSON,还是仅仅将一个JSON对象发送回客户端?@andy。我要用这个回答他的问题:)
NSString*split_message;
-(void)handleStreamMessage:(NSString*)message{
if(split_message == NULL){
split_message = @"";
}else if([split_message length] > 0){
message = [NSString stringWithFormat:@"%@%@",split_message,message];
}
NSLog(@"message:%@",message);
NSError *error;
NSData* data = [message dataUsingEncoding:NSUTF8StringEncoding];
if ([NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error] == nil)
{
// not finished the stream as not given proper json data
split_message = message;
}else{
[self handleIncomingNotification:message];
split_message = @"";
}
}