gpt4 book ai didi

ios - 如何使用 GCD 使用 CFStreams

转载 作者:塔克拉玛干 更新时间:2023-11-02 09:46:25 26 4
gpt4 key购买 nike

我是ios新手..

我想使用套接字连接到服务器,我按照给出的教程进行操作 here

这工作正常,但我在主 UI 线程中做所有事情,但是 View 被卡住,直到我得到服务器的响应...所以我在 google 上搜索了一下,发现 ios 中的 GCD 的概念。 . 所以在我的按钮上单击我调用以下代码...

    [SVProgressHUD showWithStatus:@"Processing.."];
[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)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)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 selector:@selector(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)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)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;

}

最佳答案

如果您在单独的线程上运行它,那么您必须处理运行循环。你必须调用

[[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/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com