我有一个服务器可以使用 select-accept 处理多个客户端。
客户端可以连接并向服务器发送消息,服务器可以随时向任何客户端发送消息。 客户端使用 accept 检查消息的标准输入和套接字。
假设有两个客户端同时连接。第一个客户端开始向服务器输入消息,同时(作为第二个客户端消息的结果)服务器向第一个客户端发送消息。第一个客户端在换行后立即显示服务器消息,中断控制台输入。然后第一个客户端重新输入消息并按回车键,但问题是消息的未完成部分(在服务器消息到达之前输入)也被发送。
控制台可能的结果:
./client
Server says: Hi Tom! Use commands get, set, exit.
Tom> exi
Server says: Your friend<Peter> arrived.
Tom> exit
在上面的示例中,客户端 (Tom) 尝试发送退出。
./server
Waiting connections...
Tom arrived.
Peter arrived. Notifying friends: Tom...
Tom -> exiexit
服务器得到 exiexit
而不是 exit
。
问题是如何清理输入?我尝试了以下方法和组合:
std::cin.ignore(INT_MAX);
std::cin.ignore(INT_MAX, '\n');
while ((ch = getchar()) != '\n' && ch != EOF);
scanf("%c%*[^\n]%*c", &c);
std::getline(std::cin, buffer);
gets(buffer);
std::cin.sync();
std::cin.seekg(0, std::cin.end);
但主要问题要么是操作阻塞,因此我必须按回车键,要么是它不清除输入,或者两者兼而有之。
最佳答案
这是在可移植的 C/C++ 中不容易完成的事情。您需要做的是与终端进行更强烈的交互,以便您可以精确控制发生的事情。
例如,在 Linux 上,有一个 ncurses 库可以帮助您在终端中移动光标并逐个字符地读取而无需行缓冲等。这将允许您在标准输出上重新打印部分输入行,以便用户可以看看到底发生了什么。低级 API 是 termios(参见 man 3 termios
)。
在 Windows 上也有类似的可能性,但界面却截然不同,console familiy of functions .
关于C++清除输入缓冲区(最后没有换行符),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20272087/