Linux 终端不显示字符
Linux terminal won't display characters
我正在编写跨平台控制台聊天,遇到一个奇怪的问题:
- 我在一个终端启动我的服务器。
- 我正在另一个终端启动我的客户端。
- 然后我从客户端连接到服务器。
- 交换数据。
- 服务器和客户端关闭。
然后问题来了:终端不显示字符(当你输入密码时 - 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
标志。这意味着输入的字符将不再直接显示。
我正在编写跨平台控制台聊天,遇到一个奇怪的问题:
- 我在一个终端启动我的服务器。
- 我正在另一个终端启动我的客户端。
- 然后我从客户端连接到服务器。
- 交换数据。
- 服务器和客户端关闭。
然后问题来了:终端不显示字符(当你输入密码时 - 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
标志。这意味着输入的字符将不再直接显示。