2011-03-26 43 views
0

我其实不知道如何找到我的问题的最佳标题,但请让我解释...处理的协议请求和响应通过TCP

在我的应用我要实现的问题/答案类型TCP协议在客户端发送问题,等待一个或多个答案然后发送后续问题。

的问题,只是正常发送,而接收到的答案触发回调-(void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag

这里的主循环:

- (void) doQandA { 
    BOOL ok; 
    int runMessages[7] = {0,1,2,3,2,0,3}; 
    int msgIndex = 0; 
    int msgNumber = runMessages[msgIndex]; 

    waitingForResponse = FALSE; 
    while (msgIndex < 6) { 
     if (!waitingForResponse) { 
      ok = [self sendQuestionMsg: msgNumber]; 
      msgIndex++; 
      msgNumber = runMessages[msgIndex]; 
     } 
    } 
} 

,其中,发送居然是......

- (void) sendQuestionMsg: (int) msgNo { 

    //sendMsg over TCP 
    [self sendQuestionNo: msgNo]; 
    waitingForResponse = TRUE; 
} 

而且收到答案...

-(void)onSocket:(AsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag { 
    [self handleAnswer: data]; 
} 

-(void) handleAnswer: (NSData*) data { 
    //do stuff 
    waitingForResponse = FALSE; 
} 

这实际上是这样做的正确方法吗?我担心我的主doQandA循环太CPU密集。没有更好的方法等待答案吗?

我希望能澄清我的问题... 非常感谢

回答

1

答案是否定的,这是不正确的方法。

您实施的方法称为繁忙等待循环。 doQandA()中的循环始终处于执行状态 - 您绝对有权担心这一点。

正确的做法是在该循环中有一个阻塞调用 - 一个调用会暂停您的进程直到发生事件。在这种情况下,您正在等待的事件是要到达的网络数据包。

通常的方式做到这一点是在诸如read()recv()poll()select()系统调用,当网络分组到达将返回方框。然后您将直接从主循环中调用didReadData()函数。