Linux 终端不显示字符

Linux terminal won't display characters

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

  1. 我在一个终端启动我的服务器。
  2. 我正在另一个终端启动我的客户端。
  3. 然后我从客户端连接到服务器。
  4. 交换数据。
  5. 服务器和客户端关闭。

然后问题来了:终端不显示字符(当你输入密码时 - OS 得到我的字符,但不显示)。当我输入 'Enter' 时它会显示 - 我输入的所有内容正在执行。

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

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

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

void Chat::getMessageFromUser(string &message) {
    message = "";
    strcpy(Chat::currentMessage, this->getMessageSigningUp().c_str());

    char newChar = '[=11=]';
    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] = '[=11=]';
    *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()有问题?或者我没有关闭某些东西?有什么问题吗?

是的,getch() 函数中的以下代码停用了直接输出:

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

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