0

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

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
        }
      }
    }
  }
}

问题是,当我按下键盘上的“回车”键并激活“0”文件描述符时,程序将永远不会激活任何其他文件描述符,它会锁定“0”文件描述符。我该如何修复这个错误?

4

1 回答 1

1

您需要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;
  }
}
于 2013-11-02T21:40:02.927 回答