mit QTextStream zum Lesen von stdin in eine non-blocking Mode
Qt, ich bin versucht, den Inhalt zu Lesen von stdin-stream im non blocking Mode. Ich bin mit dem QSocketNotifier zu Benachrichtigen, wenn der socket erhielt einige neue Daten. Das setup für den notifier sieht wie folgt aus:
QSocketNotifier *pNot = new QSocketNotifier(STDIN_FILENO, QSocketNotifier::Read, this);
connect(pNot, SIGNAL(activated(int)), this, SLOT(onData()));
pNot->setEnabled(true);
Den onData()
slot sieht so aus:
void CIPCListener::onData()
{
qDebug() << Q_FUNC_INFO;
QTextStream stream(stdin, QIODevice::ReadOnly);
QString str;
forever
{
fd_set stdinfd;
FD_ZERO( &stdinfd );
FD_SET( STDIN_FILENO, &stdinfd );
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 0;
int ready = select( 1, &stdinfd, NULL, NULL, &tv );
if( ready > 0 )
{
str += stream.readLine();
}
else
{
break;
}
}
qDebug() << "Recieved data:" << str;
}
Wie Sie sehen können ich bin versucht, die select () - Systemaufruf, um mir zu sagen, wenn ich schon Daten zu Lesen. Jedoch in der Praxis was geschieht, ist die select () - Aufruf gibt 0 zurück, nachdem ich gelesen habe, die erste Zeile des Textes. So, zum Beispiel, wenn ich schreib 5 Zeilen text, um den Prozess stdin-stream, den ich immer nur Lesen der ersten Zeile.
Was das problem sein könnte?
- haben Sie versucht, readAll anstelle von readLine?
- yup. Ich denke, es nutzt atEnd() intern zu erkennen, wenn es ist erreicht, das Ende des Streams. Das Ergebnis ist, dass es blockiert immer.
- ok, die einzige andere Sache, die ich denken kann, versucht, die Abschaffung der aktuellen Umsetzung (select call) und tun etwas ähnlich, was der Assistant unterstützt, finden Sie unter tools\Assistent\tools\Assistent\remotecontrol*
- Dieser code ist in Ordnung, wenn ich Eingang direkt in das terminal. Es ist genug für mich... Danke. 😉
Du musst angemeldet sein, um einen Kommentar abzugeben.
Linie der Pufferung.
Standard ist die Spülung nach einem "\n". Wenn du schreibst 5 Zeilen zu Ihrem Verfahren, Ihren Schlitz bekommt 5-mal aufgerufen. Wenn Sie vermeiden wollen, dass Sie anrufen setbuf(stdin, _IOFBF). Aber selbst dann ist nicht gewährleistet, die Sie Lesen können beliebig große Datenmengen in einem Stück.
Edit: Es wäre wahrscheinlich besser, verwenden Sie QTextStream::atEnd() anstelle von select, da QTextStream hat seine eigenen internen Puffer.
Habe ich gefunden und Beispiel in der anderen Antwort, die passt fast zu dieser Frage und mit einer vollständigen und einfachen code:
https://stackoverflow.com/a/7389622/721929
Ich verwendet habe, es zu implementieren Sie ein QT-Konsole-basierte Anwendung, die einen Text-Menü zu wählen, auf der Auswahl des Benutzers.