Wie kann ich, ohne zu blockieren einzelne Tastenanschläge in einer Unix-Konsole App erfassen?

StackOverflow https://stackoverflow.com/questions/184108

  •  06-07-2019
  •  | 
  •  

Frage

Ich habe einen sehr einfacher TCP-Server in C. geschrieben auf unbestimmte Zeit läuft, für Verbindungen zu warten. Unter Windows verwende ich select für die Aktivität auf dem Sockel zu überprüfen, und wenn es nicht ist, ich habe den folgenden Code mich durch Schlagen ‚q‘ auf der Tastatur zu beenden zuzulassen:

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

Das funktioniert nicht auf Unix, da kbhit nicht existiert und getch funktioniert anders. Ich fand einige Beispielcode dass Terminaleinstellungen verwendet tcsetattr und Eingabe ermöglichen Zeichen-für-Zeichen zu ändern. Nach der init-Funktion aufrufen, ich öffne / dev / stdin (mit O_NONBLOCK) und ein Zeichen lesen, aber read( f, &c, 1 ) blockiert, bis ein Charakter getroffen wird.

Ich glaube, ich könnte einen separaten Thread laichen und habe es auf unbestimmte Zeit warten, und dann wird das Signal den ersten Thread, wenn die ‚q‘ Benutzer-Hits, aber das ist ein wenig plump erscheint. Sicherlich gibt es einen einfacheren Weg?

War es hilfreich?

Lösung

Fügen Sie stdin in die Liste der Auswahlgriffe, und wenn es Daten hat, lesen Sie rufen ein Zeichen von ihm zu lesen.

Andere Tipps

Rather, fügen Sie "f" von Ihrem

read( f, &c, 1 )

Anruf auszuwählen. Wenn f bereit für Lese ist, hat ein Zeichen gedrückt wurde, und lesen () nicht blockieren.

In Unix, ob auf der Systemkonsole oder in einem X-Terminal-Fenster, Tastatur I / O geht durch ein virtuelles Terminal. Gerät / dev / tty ist die übliche Art und Weise, in diesen Tagen, eines Prozesses, der Steuerdatenstation zugreift. Vorrichtung Manipulationen andere als Öffnen / Schließen / Lesen / Schreiben sind alle von der ioctl behandelt (2) Systemaufruf für dieses spezielle Gerät. Die allgemeine Vorstellung von dem, was Sie tun möchten, ist

Öffnen Sie den Steueranschluss (das kann oder nicht sein stdin)

ändern Sie den Betriebsmodus auf diesem Terminal zurück, ohne für eine volle Linie des Eingangs zu warten (was die normale Standardeinstellung)

mit dem Rest des Programms weiter, wohl wissend, dass von diesem Terminal liest (was könnte stdin) zurückkehren Teillinien oder sogar Null-Zeichen ohne es Bedingung eines Fehlers oder eine Kündigung zu sein.


Eine detaillierte Antwort auf wie der zweite Schritt zu tun ist an der C-Programmierung FAQ . Sie weisen darauf hin, dass dies eine O Frage, keine Sprache Frage. Sie bieten neun Möglichkeiten, aber die drei wichtigsten sind relevant zu dieser Frage sind

  1. Verwenden Sie die Flüche (3) Bibliothek
  2. Old BSD-Systeme, Verwendung sgttyb einstellen cbreak oder RAW
  3. Posix oder alte V-Stil Systeme System verwenden TCGETAW / TCSETAW einstellen c_cc [VMIN] auf 1 und c_cc [VTIME] auf 0.

ein paar Referenzen in der C-FAQ Nach könnte dazu führen, dieser Seite des kbhit Codefragmente .

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top