Обработка запросов и ответов в протоколах по TCP - PullRequest
0 голосов
/ 26 марта 2011

На самом деле я не уверен, как найти лучшее название для моего вопроса, но, пожалуйста, позвольте мне объяснить ...

В моем приложении мне нужно реализовать протокол «вопрос / ответ» по протоколу 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 слишком сильно загружает процессор. Разве нет лучшего способа ожидания ответов?

Я надеюсь, что смогу прояснить свой вопрос ... Большое спасибо

1 Ответ

1 голос
/ 28 марта 2011

Ответ - нет, это неправильный подход.

То, что вы реализовали, называется циклом busy-wait . Цикл в doQandA() вращается, постоянно выполняется, все время - вы определенно правы, что беспокоитесь об этом.

Правильнее всего сделать блокирующий вызов в этом цикле - вызов, который приостанавливает ваш процесс до тех пор, пока не произойдет событие. В этом случае ожидаемое событие - это прибывающий сетевой пакет.

Обычный способ сделать это - заблокировать системный вызов, такой как read(), recv(), poll() или select(), который будет возвращаться при поступлении сетевого пакета. Затем вы отправите функцию didReadData() непосредственно из основного цикла.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...