如何同时处理用户交互和套接字事件

How do I handle user interaction and sockets events simultaneously?

本文关键字:套接字 事件 交互 用户 何同时 处理      更新时间:2023-10-16

我正在编写一个使用ncurses作为接口的聊天程序。我应该如何同时处理套接字文件描述符和用户交互?我的想法如下。现在的问题是,对于我按下的每个按钮,循环只执行一次。如何构建我的程序,使套接字和用户交互在准备好后立即得到处理?我试着让我的民意调查包括标准输入和输出的文件描述符,但这不起作用。

while(ch = getch()) {
   poll sockets
   loop sockets {
      ...
   }
   switch(ch) {
      ...
   }
} 

也是一个更普遍的问题。一个人通常是如何编写程序来同时处理用户交互和其他事情的?似乎有一种标准的方法可以做到这一点。

您可以在输入屏幕上尝试nodelay()

nodelay(stdscr,TRUE); // turn off getch() blocking
while(getch() == ERR)
{
    //do other stuff
}
else
    //handle input

但很可能你会想继续走下去。

建立一个文件描述符集(FD_set),其中包括STDIN以及您试图读取的套接字,然后在该集上使用select()。类似以下内容::

int main(int argc, char **argv)
{
  fd_set fds;
  int fd = open(/* your socket */);
  struct timeval tv;
  FD_ZERO(&fds);
  FD_SET(STDIN_FILENO, &fds);
  FD_SET(fd, &fds);
  while (1) {
     tv.tv_sec = 1; // wait for up to 1 sec
     int retval = select(2, &fds, NULL, NULL, &tv);
     if (retval > 0) {
        if (FD_ISSET(STDIN_FILENO, &fds)) 
            // process stdin
        else if (FD_ISSET(fd, &fds))
            // process data from your socket
     } else if (retval == 0) 
        // timeout
     else
        // some error
   }
   exit 0;
}

(注意,我没有编译这个,但你应该知道这个想法。)

请参阅fd_set并选择教程