菜鸟教程小白 发表于 2022-12-13 03:02:38

ios - 如何使用 GCD 使用 CFStreams


                                            <p><p>我是ios新手..</p>

<p>我想使用 Socket Connection 连接到服务器,我按照给出的教程进行操作
<a href="http://www.raywenderlich.com/3932/how-to-create-a-socket-based-iphone-app-and-server" rel="noreferrer noopener nofollow">here</a> </p>

<p>这工作正常,但我在主 UI 线程中做所有事情,但 View 被卡住,直到我从服务器得到响应......所以我用谷歌搜索了一下,在 ios 中找到了 GCD 的概念。 . 所以在我的按钮点击我调用下面的代码...</p>

<pre><code>    ;
    ;


qt = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_async(qt, ^{
CFReadStreamRef readStream;
CFWriteStreamRef writeStream;
CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)ip, 54000, &amp;readStream, &amp;writeStream);

inputStream = (NSInputStream *)readStream;
outputStream = (NSOutputStream *)writeStream;
;
;

forMode:NSDefaultRunLoopMode];
forMode:NSDefaultRunLoopMode];

;
;

NSData *data = [ initWithData:];
maxLength:];
;
    });
</code></pre>

<p>我正在使用函数处理事件</p>

<pre><code>- (void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent {

    NSLog(@&#34;StreamEvent %i&#34;,streamEvent);
    switch (streamEvent) {

                            dispatch_async(dispatch_get_main_queue(), ^{;
            });

      case NSStreamEventOpenCompleted:
            NSLog(@&#34;Stream opened&#34;);
            break;

      case NSStreamEventHasBytesAvailable:
               NSLog(@&#34;Stream has byte Avaliable&#34;);

            if (theStream==inputStream) {

                while () {
                  uint8_t buffer;
                  int len;
                  len = ;
                  if(len&gt;0){
                        NSString *output = [ initWithBytes:buffer length:len encoding:NSASCIIStringEncoding];
                        ;

                        NSLog(@&#34;output %@&#34;,output);


                  }
                }
            }
            break;

      case NSStreamEventErrorOccurred:
            ;

            NSLog(@&#34;Can not connect to the host!&#34;);
            break;

      case NSStreamEventEndEncountered:
            ;

            break;

      default:
            ;

            NSLog(@&#34;Unknown event&#34;);

    }
}
</code></pre>

<p>使用上面的代码,我收到了一个对服务器的请求,服务器也发送了一个成功的响应,但是我在句柄事件方法中没有收到任何数据,但是我没有收到 hasbytesavaliable 事件.. 我的控制台日志是</p>

<pre><code>2013-07-02 14:06:15.312 Multi StreamEvent 1
2013-07-02 14:06:15.313 Multi Stream opened
2013-07-02 14:06:15.313 Multi StreamEvent 4
2013-07-02 14:06:15.313 Multi Unknown event
</code></pre>

<p>知道我做错了什么......</p>

<pre><code>Edit:Updated Code
</code></pre>

<p>点击按钮我启动计时器并调用连接方法..</p>

<pre><code>counter=;


      qt = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
      dispatch_async(qt, ^{;});
</code></pre>

<p>连接方式:</p>

<pre><code>CFReadStreamRef readStream;
    CFWriteStreamRef writeStream;
    CFStreamCreatePairWithSocketToHost(NULL, (CFStringRef)ip, 54000, &amp;readStream, &amp;writeStream);


    inputStream = (NSInputStream *)readStream;
    outputStream = (NSOutputStream *)writeStream;

    NSRunLoop *loop = ;

    ;
    ;

    ;
    ;

    ;
    ;

    NSData *data = [ initWithData:];
    maxLength:];
    ;

    ;
</code></pre>

<p>流句柄事件</p>

<pre><code>- (void)stream:(NSStream *)theStream handleEvent:(NSStreamEvent)streamEvent {
    Username.text = @&#34;&#34;;
    Password.text = @&#34;&#34;;
    ;
    if (counter!=nil){
      ;
      counter=nil;
    }

    NSLog(@&#34;StreamEvent %i&#34;,streamEvent);
    switch (streamEvent) {

      case NSStreamEventOpenCompleted:
            NSLog(@&#34;Stream opened&#34;);
            break;

      case NSStreamEventHasBytesAvailable:
            if (theStream==inputStream) {

                while () {
                  uint8_t buffer;
                  int len;
                  len = ;
                  if(len&gt;0){
                        NSString *output = [ initWithBytes:buffer length:len encoding:NSASCIIStringEncoding];

                        NSLog(@&#34;output %@&#34;,output);
                        ;
                        main = [
                              initWithNibName:@&#34;Mainmenu&#34;
                              bundle:nil];
                        //                        ;
                        ;
                  }
                }
            }
            dispatch_async(dispatch_get_main_queue(), ^{;
            });

            break;

      case NSStreamEventErrorOccurred:

            NSLog(@&#34;Can not connect to the host!&#34;);
            dispatch_async(dispatch_get_main_queue(), ^{;
            });

            break;

      case NSStreamEventEndEncountered:
            dispatch_async(dispatch_get_main_queue(), ^{;
            });

            break;

      default:
            NSLog(@&#34;Unknown event&#34;);
            dispatch_async(dispatch_get_main_queue(), ^{;
            });

    }
}
</code></pre>

<p>还有断开连接的方法..</p>

<pre><code>-(void) disconnect
{
    ;
    forMode:NSDefaultRunLoopMode];
    ;
    forMode:NSDefaultRunLoopMode];
    ;
    inputStream = nil;
    ;
    outputStream = nil;

}
</code></pre></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>如果您在单独的线程上运行它,那么您必须注意运行循环。你必须调用</p>

<blockquote>
<p>[ run];</p>
</blockquote>

<p>在正确的时间。</p>

<p>如下更改您的这部分代码,它肯定会工作:</p>

<pre><code>inputStream = (NSInputStream *)readStream;
outputStream = (NSOutputStream *)writeStream;

NSRunLoop *loop = ;

;
;

;
;

;
;

;
</code></pre></p>
                                   
                                                <p style="font-size: 20px;">关于ios - 如何使用 GCD 使用 CFStreams,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/17421497/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/17421497/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - 如何使用 GCD 使用 CFStreams