通过TCP处理协议中的请求和响应

时间:2011-03-26 06:48:33

标签: iphone 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 个答案:

答案 0 :(得分:1)

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

您实施的内容称为 busy-wait 循环。 doQandA()中的循环一直在旋转,不断执行 - 你担心这一点绝对是正确的。

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

执行此操作的常用方法是阻止类似read()recv()poll()select()的系统调用,这将在网络数据包到达时返回。然后,您将直接从主循环调度didReadData()函数。