编写以下程序来接收客户的消息并从键盘读取用户输入:

FD_ZERO(&masterfds);
FD_SET(udp_con, &masterfds);
FD_SET(0, &masterfds);
maxfds = udp_con;
while(exit == false)
{
  FD_ZERO(&readfds);
  readfds = masterfds;

  selectFunc = select(maxfds+1, &readfds, NULL, NULL, &tv);
  if(selectFunc < 0) {
    message("error in select");
    exit = true;
  } else {
    // The server has received something from a client
    for(i = 0; i <= maxfds; i++) {
      if(FD_ISSET(i, &readfds)) {
        if(FD_ISSET(0, &readfds)) {
          fgets(userInput, sizeof(userInput), stdin);
          int len = strlen(userInput) - 1;
          if (userInput[len] == '\n') {
            userInput[len] = '\0';
          }
          cout<<"The user said: "<<userInput<<endl;
        } else if(i == udp_con) {
          cout<<"Datagram received"<<endl;
          // After reading the user input, it never reaches here
        }
      }
    }
  }
}


问题在于,当我按下键盘上的“ enter”键并且“ 0”文件描述符被激活时,该程序将永远不会激活任何其他文件描述符,并且它将锁定在“ 0”文件描述符上。如何解决此错误?

最佳答案

FD_CLR(0, readfds)测试它后需要FD_ISSET(0, &readfds),否则它将始终采用该分支。

但是您可以通过重写算法来简化算法。养成格式化代码以使其易于阅读的习惯是个好主意。

FD_ZERO(&masterfds);
FD_SET(udp_con, &masterfds);
FD_SET(0, &masterfds);
maxfds = udp_con;

while (true) {
  readfds = masterfds;

  selectFunc = select(maxfds + 1, &readfds, NULL, NULL, &tv);
  if (selectFunc < 0) {
    message("error in select");
    break;
  }

  // Check for input on stdin (fd 0).
  if (FD_ISSET(0, &readfds)) {
    fgets(userInput, sizeof(userInput), stdin);
    int len = strlen(userInput) - 1;
    if (userInput[len] == '\n') {
      userInput[len] = '\0';
    }
    cout << "The user said: '" << userInput << "'" << endl;
  }
  // Check for input on the udp_con fd.
  if (FD_ISSET(udp_con, &readfds)) {
    cout << "Datagram received" << endl;
  }
}

关于c++ - STDIN阻止激活其他文件描述符,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19746938/

10-12 00:30