大佬教程收集整理的这篇文章主要介绍了objective-c – NSStream无法接收数据,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
socket.h中
@interface Socket : NSObject <NSStreamDelegate> - (void)connectToServerWithIP:(NSString *)ip andPort:(int)port; - (NSString *)sendmessage:(NSString *)outgoingmessage; @end
Socket.m
#import "Socket.h" @interface Socket () @property (strong,nonatomiC) NSInputStream *inputStream; @property (strong,nonatomiC) NSOutputStream *outputStream; @property (strong,nonatomiC) NSString *output; @end @implementation Socket @synthesize inputStream; @synthesize outputStream; @synthesize output; - (void)connectToServerWithIP:(NSString *)ip andPort:(int)port { CFReadStreamRef readStream; CFWriteStreamRef writeStream; CFStreamCreatePairWithSocketToHost(NULL,(__bridge CFStringRef)ip,port,&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]; } - (NSString *)sendmessage:(NSString *)outgoingmessage { NSData *messageData = [outgoingmessage dataUsingEncoding:NSUTF8StringEncoding]; const void *bytes = [messageData bytes]; uint8_t *uint8_t_message = (uint8_t*)bytes; [outputStream write:uint8_t_message maxLength:strlen([outgoingmessage cStringUsingEncoding:[NSString defaultCStringEncoding]])]; while (![inputStream hasBytesAvailable]) { usleep(10); } uint8_t buffer[1024]; [inputStream read:buffer maxLength:1023]; NSString *outputString = [NSString StringWithUTF8String:(char *)buffer]; return outputString; } - (void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent { NSLog(@"Stream Event: %lu",streamEvent); switch (streamEvent) { case NSStreamEventOpenCompleted: NSLog(@"Stream opened"); break; case NSStreamEventHasBytesAvailable: if (theStream == inputStream) { uint8_t buffer[1024]; long len; while ([inputStream hasBytesAvailable]) { len = [inputStream read:buffer maxLength:sizeof(buffer)]; if (len > 0) { output = [[NSString alloc] initWithBytes:buffer length:len encoding:NSASCIIStringEncoding]; if (output) { NSLog(@"Data: %@",output); } } } } break; case NSStreamEventErrorOccurred: NSLog(@"Can not connect to the host!"); break; case NSStreamEventEndEncountered: [theStream close]; [theStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; theStream = nil; break; default: NSLog(@"UnkNown event"); } } @end
ChatViewController.m
// // ChatViewController.m // Chat // // Created by James Pickering on 10/5/13. // Copyright (C) 2013 James Pickering. All rights reserved. // #import "ChatViewController.h" #import "LoginViewController.h" #import "StatusView.h" @interface ChatViewController () @property (strong) IBOutlet NSTableView *people; @property (strong) IBOutlet NSTextField *message; @property (strong) IBOutlet NSButton *send; @property (strong) IBOutlet NSButton *loginButton; @property (strong) IBOutlet NSButton *setTingsButton; @property (strong) IBOutlet NSButton *panicButton; @property (strong,nonatomiC) NSString *recievedText; @property (strong,nonatomiC) NSMutableArray *tableData; @property (strong,nonatomiC) NSOutputStream *outputStream; - (void)openChat:(id)sender; - (IBACtion)panic:(id)sender; - (IBACtion)logintochat:(id)sender; @end @implementation ChatViewController @synthesize sock; @synthesize recievedText; @synthesize inputStream; @synthesize outputStream; - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundLeorNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundLeorNil]; if (self) { self.isLoggedIn = falSE; sock = [[Socket alloc] init]; [sock connectToServerWithIP:@"127.0.0.1" andPort:5001]; //[self updateUI]; } return self; } - (void)updateUI { if (self.isLoggedIn) { recievedText = [sock sendmessage:@"getPeople"]; self.tableData = [[NSMutableArray alloc] initWithArray:[recievedText componentsSeparatedByString:@";"]]; NSLog(@"%@",self.tableData); [self.people reloadData]; } } - (void)openChat:(id)sender { NSLog(@"tru"); } - (IBACtion)panic:(id)sender { } - (IBACtion)logintochat:(id)sender { NSLog(@"Called"); if (self.loginPopover == nil) { NSLog(@"Login Popover is nil"); self.loginPopover = [[NSPopover alloc] init]; self.loginPopover.contentViewController = [[LoginViewController alloc] initWithNibName:@"LoginViewController" bundle:nil]; } if (!self.loginPopover.isShown) { NSLog(@"Login Popover is opening"); [self.loginButton settitle:@"Cancel"]; [self.setTingsButton setEnabled:NO]; [self.send setEnabled:NO]; [self.message setEnabled:NO]; [self.loginPopover showRelativeToRect:self.loginButton.frame ofView:self.view preferredEdge:NSMinYEdge]; } else { NSLog(@"Login Popover is closing"); [self.loginButton settitle:@"Login"]; [self.setTingsButton setEnabled:YES]; [self.send setEnabled:YES]; [self.message setEnabled:YES]; [self.loginPopover close]; } } - (NSInteger)numberOfRowsInTableView:(NSTableView *)aTableView { return [self.tableData count]; } - (id)tableView:(NSTableView *)aTableView objectValueForTablecolumn:(NSTablecolumn *)aTablecolumn row:(NSInteger)rowIndex { return [self.tableData objectATindex:rowIndex]; } - (BOOL)canBecomeKeyWindow { return YES; } - (BOOL)loginWithUsername:(NSString *)username andpassword:(NSString *)password { // Error happens here recievedText = [sock sendmessage:@"login"]; if ([recievedText isEqualToString:@"roger"]) { recievedText = [sock sendmessage:[NSString StringWithFormat:@"%@;%@",username,password]]; if ([recievedText isEqualToString:@"access granted"]) { return YES; } else { return NO; } } else { return NO; } } @end
问题是它永远挂在这一行代码上:while(![inputStream hasBytesAvailable]){},但我不明白为什么.服务器应该发回消息.
回顾some of my code看起来你应该检查案例
> NSStreamEventHasSpaceAvailable
> NSStreamEventOpenCompleted
> NSStreamEventHasBytesAvailable
> NSStreamEventEndEncountered
> NSStreamEventErrorOccurred
因此,您未检查的情况是NSStreamEventHasSpaceAvailable,这时您可以开始写入您的流.
编辑:再次读取代码,我在sendmessage操作中看到您正在使用outputStream对象而不是委托来编写,然后自己完成工作以从inputStream中读取.我想您可能想要使用委托,而不是直接从您的输入流中读取,因为它将极大地简化您的代码从网络接收数据的方式.根据我的理解,NSStream提供了一个小层抽象,围绕数据从网络缓冲的事实,因此您不需要执行诸如调用usleep之类的事情,而输入流没有可用于读取的字节.
edit2:我读到你的代码永远不会过去的更新(![inputStream hasBytesAvailable])并且很明显问题是你没有正确使用你的流.我看到它的方式,使用NSStream的最好方法是使用handleEvent:(NSStreamEvent)事件方法响应事件,并且永远不会直接告诉它写入字节,或者在它有可用字节之前休眠.
在我链接到你的代码中,我有一个readDelegate和一个writeDelegate都处理NSStreams,你可能想看看我如何使用我的writeDelegate here.我基本上有一个方法,addCommand:(NSString *)命令放将流写入队列的字符串,然后当我的流委托可以写入字节(NSStreamEventHasSpaceAvailablE)时,我尽可能多地写入字节.我希望这有帮助!
以上是大佬教程为你收集整理的objective-c – NSStream无法接收数据全部内容,希望文章能够帮你解决objective-c – NSStream无法接收数据所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。