2013-11-28 59 views
1

我有一個服務器可以通過select-accept處理多個客戶端。C++清除輸入緩衝區(最後無新行)

客戶端可以連接併發送消息到服務器,服務器可以隨時向任何客戶端發送消息。 客戶端使用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); 

但主要的問題,或者操作框,所以我必須按回車,或者doen't乾淨的輸入,或兩者兼而有之。

回答

1

這是在便攜式C/C++中不容易完成的事情。您需要做的是與終端進行更強大的互動,以便您可以精確控制發生的情況。

例如,在Linux上,有一個ncurses庫,它可以幫助您在終端中移動光標並逐字讀取而不用行緩衝等。這將允許您重新打印stdout上的部分輸入行,以便用戶可以看到實際發生了什麼。此低級API爲termios(請參閱man 3 termios)。

在Windows上有類似的可能性,但有一個非常不同的接口console familiy of functions

+0

是的,我能用ncurses解決問題。只有標準庫,在顯示服務器消息「按Enter鍵繼續」之後,將整行讀入一個臨時變量。在Windows上可以使用conio.h中的函數,比如getch。謝謝 – Attila