我是ios新手..
我想使用 Socket Connection 连接到服务器,我按照给出的教程进行操作
here
这工作正常,但我在主 UI 线程中做所有事情,但 View 被卡住,直到我从服务器得到响应......所以我用谷歌搜索了一下,在 ios 中找到了 GCD 的概念。 . 所以在我的按钮点击我调用下面的代码...
[SVProgressHUD showWithStatus"rocessing.."];
[self.view setUserInteractionEnabled:NO];
qt = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(qt, ^{
CFReadStreamRef readStream;
CFWriteStreamRef writeStream;
CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)ip, 54000, &readStream, &writeStream);
inputStream = (NSInputStream *)readStream;
outputStream = (NSOutputStream *)writeStream;
[inputStream setDelegate:self];
[outputStream setDelegate:self];
[inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[inputStream open];
[outputStream open];
NSData *data = [[NSData alloc] initWithData:[pinno dataUsingEncoding:NSASCIIStringEncoding]];
[outputStream write:[data bytes] maxLength:[data length]];
[outputStream close];
});
我正在使用函数处理事件
- (void)streamNSStream *)theStream handleEventNSStreamEvent)streamEvent {
NSLog(@"StreamEvent %i",streamEvent);
switch (streamEvent) {
dispatch_async(dispatch_get_main_queue(), ^{[SVProgressHUD dismiss];
});
case NSStreamEventOpenCompleted:
NSLog(@"Stream opened");
break;
case NSStreamEventHasBytesAvailable:
NSLog(@"Stream has byte Avaliable");
if (theStream==inputStream) {
while ([inputStream hasBytesAvailable]) {
uint8_t buffer[1024];
int len;
len = [inputStream read:buffer maxLength:sizeof(buffer)];
if(len>0){
NSString *output = [[NSString alloc] initWithBytes:buffer length:len encoding:NSASCIIStringEncoding];
[self.view setUserInteractionEnabled:YES];
NSLog(@"output %@",output);
}
}
}
break;
case NSStreamEventErrorOccurred:
[self.view setUserInteractionEnabled:YES];
NSLog(@"Can not connect to the host!");
break;
case NSStreamEventEndEncountered:
[self.view setUserInteractionEnabled:YES];
break;
default:
[self.view setUserInteractionEnabled:YES];
NSLog(@"Unknown event");
}
}
使用上面的代码,我收到了一个对服务器的请求,服务器也发送了一个成功的响应,但是我在句柄事件方法中没有收到任何数据,但是我没有收到 hasbytesavaliable 事件.. 我的控制台日志是
2013-07-02 14:06:15.312 Multi[899:1c03] StreamEvent 1
2013-07-02 14:06:15.313 Multi[899:1c03] Stream opened
2013-07-02 14:06:15.313 Multi[899:1c03] StreamEvent 4
2013-07-02 14:06:15.313 Multi[899:1c03] Unknown event
知道我做错了什么......
Edit:Updated Code
点击按钮我启动计时器并调用连接方法..
counter=[NSTimer scheduledTimerWithTimeInterval:30.0 target:self selectorselector(stream:handleEvent userInfo:nil repeats:NO];
qt = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(qt, ^{[self connect];});
连接方式:
CFReadStreamRef readStream;
CFWriteStreamRef writeStream;
CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)ip, 54000, &readStream, &writeStream);
inputStream = (NSInputStream *)readStream;
outputStream = (NSOutputStream *)writeStream;
NSRunLoop *loop = [NSRunLoop currentRunLoop];
[inputStream setDelegate:self];
[outputStream setDelegate:self];
[inputStream scheduleInRunLoop:loop forMode:NSDefaultRunLoopMode];
[outputStream scheduleInRunLoop:loop forMode:NSDefaultRunLoopMode];
[inputStream open];
[outputStream open];
NSData *data = [[NSData alloc] initWithData:[pinno dataUsingEncoding:NSASCIIStringEncoding]];
[outputStream write:[data bytes] maxLength:[data length]];
[outputStream close];
[loop run];
流句柄事件
- (void)streamNSStream *)theStream handleEventNSStreamEvent)streamEvent {
Username.text = @"";
Password.text = @"";
[self disconnect];
if (counter!=nil){
[counter invalidate];
counter=nil;
}
NSLog(@"StreamEvent %i",streamEvent);
switch (streamEvent) {
case NSStreamEventOpenCompleted:
NSLog(@"Stream opened");
break;
case NSStreamEventHasBytesAvailable:
if (theStream==inputStream) {
while ([inputStream hasBytesAvailable]) {
uint8_t buffer[1024];
int len;
len = [inputStream read:buffer maxLength:sizeof(buffer)];
if(len>0){
NSString *output = [[NSString alloc] initWithBytes:buffer length:len encoding:NSASCIIStringEncoding];
NSLog(@"output %@",output);
[SVProgressHUD dismiss];
main = [[Mainmenu alloc]
initWithNibName"Mainmenu"
bundle:nil];
// [self.view addSubview:main.view];
[self presentViewController:main animated:NO completion:NO];
}
}
}
dispatch_async(dispatch_get_main_queue(), ^{[SVProgressHUD dismiss];
});
break;
case NSStreamEventErrorOccurred:
NSLog(@"Can not connect to the host!");
dispatch_async(dispatch_get_main_queue(), ^{[self dismiss"Cannot connect to host!"];
});
break;
case NSStreamEventEndEncountered:
dispatch_async(dispatch_get_main_queue(), ^{[self dismiss"Connection Error"];
});
break;
default:
NSLog(@"Unknown event");
dispatch_async(dispatch_get_main_queue(), ^{[self dismiss"Timeout Expired"];
});
}
}
还有断开连接的方法..
-(void) disconnect
{
[inputStream close];
[inputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[outputStream close];
[outputStream removeFromRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
[inputStream setDelegate:nil];
inputStream = nil;
[outputStream setDelegate:nil];
outputStream = nil;
}
Best Answer-推荐答案 strong>
如果您在单独的线程上运行它,那么您必须注意运行循环。你必须调用
[[NSRunLoop currentRunLoop] run];
在正确的时间。
如下更改您的这部分代码,它肯定会工作:
inputStream = (NSInputStream *)readStream;
outputStream = (NSOutputStream *)writeStream;
NSRunLoop *loop = [NSRunLoop currentRunLoop];
[inputStream setDelegate:self];
[outputStream setDelegate:self];
[inputStream scheduleInRunLoop:loop forMode:NSDefaultRunLoopMode];
[outputStream scheduleInRunLoop:loop forMode:NSDefaultRunLoopMode];
[inputStream open];
[outputStream open];
[loop run];
关于ios - 如何使用 GCD 使用 CFStreams,我们在Stack Overflow上找到一个类似的问题:
https://stackoverflow.com/questions/17421497/
|