2008-10-08 29 views
4

我有一個用C編寫的非常簡單的TCP服務器。它無限期地運行,等待連接。在Windows中,我使用select檢查活動在插座上,如果沒有任何,我有以下的代碼讓我通過按鍵盤上的「Q」退出:如何在不阻塞的情況下在unix控制檯應用程序中捕獲單個按鍵?

if(kbhit()) { 
    char c = getch(); 
    if(c == 'q') break; 
} 

這並未't在unix上工作,因爲kbhit不存在,getch的工作方式不同。我發現一些sample code使用tcsetattr來更改終端設置並允許逐個字符的輸入。在調用init函數之後,我打開/ dev/stdin(使用O_NONBLOCK)並讀取一個字符,但是read(f, &c, 1)會阻塞,直到遇到一個字符。

我想我可以產生一個單獨的線程,並有無限期地等待,然後發出第一個線程,如果用戶點擊'q',但這似乎有點笨重。當然有更簡單的方法?

回答

5

將stdin添加到您的選擇句柄列表中,如果它具有數據,則調用read從中讀取一個字符。

+0

即使我的應用程序還沒有使用select,這也會起作用。我使用select的事實已經非常容易,它的作用就像一個魅力。謝謝 – 2008-10-08 21:45:52

1

相反,從

read(f, &c, 1) 

加上 「F」,選擇呼叫。當f準備好讀取時,一個字符被按下,並且read()不會被阻塞。

1

在Unix中,無論是在系統控制檯還是在X終端窗口中,鍵盤I/O都會通過虛擬終端。 Device/dev/tty是最近訪問進程控制終端的常用方式。除了打開/關閉/讀取/寫入以外的設備操作都由該特定設備的ioctl(2)系統調用處理。你想要做什麼的總體思路是

打開控制終端(這可能會或可能不會進行標準輸入)

變化是終端上的操作模式返回,而無需等待輸入一個完整的行(是正常的默認設置)

繼續執行程序的其餘部分,知道從該終端(可能是stdin)的讀取可能會返回部分行甚至零個字符,而不會出現錯誤或終止條件。


有關如何完成第二步的詳細答案請參見C-programming faq。他們還指出,這是一個操作系統問題,而不是語言問題。他們提供9級的可能性,但有關這個問題的三個主要的有

  1. 使用詛咒(3)庫
  2. 舊BSD風格的系統,使用的sgttyb設置CBREAK或RAW
  3. Posix的或舊的系統V風格來系統,使用TCGETAW/TCSETAW設置c_cc中[VMIN]爲1而c_cc [VTIME] 0

繼在C FAQ一對夫婦的引用可能導致到this page of kbhit code fragments

相關問題