2013-02-05 30 views
3

我發現GCDAsyncSocket的didReadData回調不直觀的一件事是它不會再次調用,除非您發出另一個readData。爲什麼這樣設計?期望圖書館的用戶發起另一個讀取電話以獲得回調或者這是一個設計缺陷是否正確?爲什麼GCDAsyncSocket readData設計爲只讀一次?

例如

- (void)socket:(GCDAsyncSocket *)sock didAcceptNewSocket:(GCDAsyncSocket *)newSocket { 
    ... 
    // initiate the first read 
    self.socket = newSocket; 
    [self.socket readDataWithTimeout:-1 tag:0]; 
} 

- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag { 
    // do what you need with the data... 

    // read again, or didReadData won't get called! 
    [self.socket readDataWithTimeout:-1 tag:0]; 
} 

回答

6

爲什麼這樣設計?

只要您只使用readDataWithTimeout:tag:只要有新數據到達時調用委託方法就可以看起來更直觀。

但是readDataWithTimeout:tag:不是用GCDAsyncSocket讀取數據的唯一方法。還有例如readDataToLength:withTimeout:標籤:readDataToData:withTimeout:標籤:

這兩種方法調用的特定點的輸入數據的代表,你可能想打電話給在不同位置有不同的人在你的處理。例如,如果您正在處理的流格式中有一個CRLF分隔標題,後面跟着一個長度爲標題中提供的可變長度主體,那麼您可能需要在之間調用readDataToData:withTimeout:tag:來讀取你知道分隔符的標題,然後readDataToLength:withTimeout:tag:來讀取你從標題中拉出的長度。

1

這是正確的;您需要繼續使用委託方法的讀取循環。

0

擴大在什麼西蒙·詹金斯說:

- (void)socket:(GCDAsyncSocket *)sock didWriteDataWithTag:(long)tag 
    { 

     // This method is executed on the socketQueue (not the main thread) 
     switch (tag) { 
      case CHECK_STAUTS: 
       [sock readDataToData:[GCDAsyncSocket ZeroData] withTimeout:READ_TIMEOUT tag:CHECK_STAUTS]; 
       break; 

      default: 
       break; 
     } 


    } 



    - (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag 
    { 
     // This method is executed on the socketQueue (not the main thread) 
    dispatch_async(dispatch_get_main_queue(), ^{ 
      @autoreleasepool { 

       if (tag == CHECK_STAUTS) { 
    //TODO: parse the msg to find the length. 
    NSString *msg = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]; 

        [serverSocket readDataToLength:LENGTH_BODY withTimeout:-1 tag:CHECK_STAUTS_BODY]; 

       } else if (tag == CHECK_STAUTS_BODY) { 
//TODO: parse the msg to the body content 
    NSString *msg = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]; 
       } 

      } 
     }); 


     // Echo message back to client 
     //[sock writeData:data withTimeout:-1 tag:ECHO_MSG]; 
    }