Linux终端不会显示字符

时间:2015-09-15 18:10:35

标签: c++ linux multithreading gnome-terminal

我正在编写一个跨平台的控制台聊天并遇到一个奇怪的问题:

  1. 我在一个终端启动我的服务器。
  2. 我在另一个终端开始我的客户。
  3. 然后我从客户端连接到服务器。
  4. 交换数据。
  5. 服务器和客户端已关闭。
  6. 然后出现了问题:终端中没有显示的字符(当您输入密码时 - 操作系统获取我的字符,但不显示它)。它显示我输入'Enter'时 - 我输入的所有内容。

    服务器有很多线程:main(用于向客户端发送消息),用于接受和连接的每个客户端。

    客户端有2个线程:main(用于向服务器发送消息)和接收消息。

    所有接收操作都是异步的(我使用select()方法)
    我正在使用以下内容从用户那里收到消息:

    void Chat::getMessageFromUser(string &message) {
        message = "";
        strcpy(Chat::currentMessage, this->getMessageSigningUp().c_str());
    
        char newChar = '\0';
        int newCharPtr = this->getCurrentMessageLength();
        int minLength = newCharPtr;
        *this->output << Chat::currentMessage;
    
        while ((newChar = Chat::getch()) != '\n' && newCharPtr < Chat::MESSAGE_MAX_LENGTH) {
            if (newChar == 127) {     //127 is code of '\b' (backspace button)
                if (newCharPtr == minLength)
                    continue;
    
                *this->output << "\b \b";
                --newCharPtr;
                continue;
            }
            *(Chat::currentMessage + newCharPtr) = newChar;
            *this->output << newChar;
            ++newCharPtr;
        }
        Chat::currentMessage[newCharPtr] = '\0';
        *this->output << endl;
    
        message = Chat::currentMessage;
    
        memset(Chat::currentMessage, 0, Chat::getCurrentMessageLength());
        strcpy(Chat::currentMessage, this->getMessageSigningUp().c_str());
    }
    

    我用它来处理下一个情况: 一个用户输入消息,并在此时receiveThread获取新消息。在这种情况下,我使用以下内容添加新消息:

    void Chat::putMessageInChat(const char *message) {
        for (int i = 0; i < Chat::getCurrentMessageLength(); ++i)
            *this->output << "\b \b";
        *this->output << message << endl;
        *this->output << Chat::getCurrentMessage();
    }
    

    getch()方法如下:

    int Chat::getch() {
        struct termios oldt,
        newt;
        int ch;
        tcgetattr( STDIN_FILENO, &oldt );
        newt = oldt;
        newt.c_lflag &= ~( ICANON | ECHO );
        tcsetattr( STDIN_FILENO, TCSANOW, &newt );
        ch = getchar();
        tcsetattr( STDIN_FILENO, TCSANOW, &oldt );
        return ch;
    }
    

    可能getch()有问题吗?或者我不是很亲密的东西?有什么问题?

1 个答案:

答案 0 :(得分:2)

是的,getch()功能中的以下代码会停用直接输出:

newt.c_lflag &= ~( ICANON | ECHO );
tcsetattr( STDIN_FILENO, TCSANOW, &newt );

您正在删除ECHO标记。这意味着键入的字符将不再直接显示。