首页 > 解决方案 > 为什么 fd_set(file descriptor) 会阻止终端输出直到超时?

问题描述

我使用了这个存储库,它是一个类似于 Boost.Asio 的结构,它在 C++ 中实现消息传递和双端队列以及客户端和服务器通信。

问题是,它是为 Windows 编写的,在文件 SimpleClient.cpp 中,从命令行读取按键,现在我想在 Ubuntu 终端上读取命令行按键,因此我在使用 fd_set 的堆栈上找到了这个问题,我把它放在了函数,然后在SimpleClient文件中:

void task1_getkeyboard(CustomClient *c)
{
    struct termios oldSettings, newSettings;

    tcgetattr( fileno( stdin ), &oldSettings );
    newSettings = oldSettings;
    newSettings.c_lflag &= (~ICANON & ~ECHO);
    tcsetattr( fileno( stdin ), TCSANOW, &newSettings );
    
    
    fd_set set;
    struct timeval tv;

    tv.tv_sec = 5;
    tv.tv_usec = 0;

    FD_ZERO( &set );
    FD_SET( fileno( stdin ), &set );

    int res = select( fileno( stdin )+1, &set, NULL, NULL, &tv );
    char cinif;

    if( res > 0 )
    {
    
        read( fileno( stdin ), &cinif, 1 );
        //printf( "Input available %c\n" , cinif);
            if ( cinif == 'p' ) {
            c->PingServer();
            cinif = '\0';
        }
    
    }
        else if( res < 0 )
        {
            perror( "select error" );
            //break;
        }
        else
        {
            printf( "Select timeout\n" );
        }
}

我已经把函数放在了while循环中:

...
while (!bQuit)
    {
        task1_getkeyboard(&c);
    if (c.IsConnected())
    {
...

问题是,它会阻止终端直到超时,例如在成功连接时,客户端应该打印服务器接受的连接但它等待 5 秒(fd_set 超时)。我该如何解决这个问题?

标签: c++terminalclient-serverboost-asiostdin

解决方案


推荐阅读