2012-07-12 9 views
1

qsocketnotifier를 TCP 소켓과 함께 사용하려고하면 소켓에서 읽을 데이터가 없을 때에도 qsocketnotifier가 지속적으로 "활성화 된"신호를 발생시킵니다. . 나는 소켓에서 "blocking"과 "non blocking"모드를 시도했다. 행동은 동일합니다. 어떤 시체도 언제든지 이것을 보았습니까? 아래 코드 조각을 붙여 넣습니다. QSocketNotifier docs에서소켓에 0 데이터가 있어도 qsocketnotifier가 지속적으로 활성화 된 신호를 발생시킵니다.

QSocketNotifier *notifier = new QSocketNotifier(gwSocketId, QSocketNotifier::Read, this); 
    connect(notifier, SIGNAL(activated(int)), this, SLOT(processClientEvents())); 

답변

3

: 클래스가 QSocketNotifier라고하지만

, 그것은 일반적으로 소켓 이상의 장치 다른 유형에 사용됩니다. QTcpSocket 및 QUdpSocket은 신호를 통해 알림을 제공하므로 일반적으로 QSocketNotifier를 사용할 필요가 없습니다.

QTcpSocketQIODevice로부터 상속 따라서 신호 readyRead()있다. 나는이 신호가 당신이 추구하는 것이라 생각합니다.

1

QSocketNotifier + QTextStream을 사용하여 stdin에서 읽는 것과 같은 문제가있었습니다. 한 줄로 여러 줄을 응용 프로그램에 보내면 QSocketNotifier :: activated() 신호를 더 많이 읽게됩니다. 차단 될 QTextStream :: readLine() 호출이 추가로 생겨서 다른 행을 전송할 때까지 앱에서 이벤트 처리가 중단됩니다.

QTextStream :: readAll을 사용하여 시도했지만 항상 파일 끝까지 차단하여 맨 처음 QSocketNotifier :: activated() 신호에서 문제가 발생하도록합니다.

QTextStream :: readLine() 호출을 차단하기 전에 stdin에서 실제로 읽어야 할 데이터가 있는지 여부를 확인하는 방법을 알아 내려고 시도한 후 QTextStream을 사용하지 않고 fgets) 대신. 이것은 내 문제를 해결 한 것 같다.

다음은 몇 가지 예제 코드입니다 (실제로는 큰 선을 처리하도록 조정되지 않았습니다. 독자의 연습 문제입니다). 바라기를 이것은 나가 밖으로 이것을 시도하는 것을 통해 처음부터 끝까지 두통을 거기 밖으로 누군가 저장할 것이다. 차단 된 상태로 전환했는지 알 수있는 확실한 방법이기 때문에 일부 신호/이벤트 처리가 발생했습니다.

예 StdinReader 헤더 :

#include <QCoreApplication> 
#include <QSocketNotifier> 
#include <QTimer> 
#include <cstdio> 

class StdinReader : public QObject 
{ 
    Q_OBJECT 

public: 
    StdinReader(QObject* parent = 0) 
    : QObject(parent), 
     notifier(new QSocketNotifier(fileno(stdin), QSocketNotifier::Read, this)) 
    { 
    connect(this, SIGNAL(sigOutputData(QString)), SLOT(outputData(QString))); 
    connect(notifier, SIGNAL(activated(int)), SLOT(consumeData())); 
    notifier->setEnabled(true); 
    QTimer::singleShot(1000, this, SLOT(timerTick())); 
    } 

    ~StdinReader() { } 

signals: 
    void sigOutputData(QString); 

private slots: 
    void outputData(QString data) 
    { 
    fprintf(stdout, "Data: %s\n", data.trimmed().toUtf8().constData()); 
    fflush(stdout); 
    } 

    void timerTick() 
    { 
    emit sigOutputData(QString::fromUtf8("tick")); 
    QTimer::singleShot(1000, this, SLOT(timerTick())); 
    } 

    void consumeData() 
    { 
    notifier->setEnabled(false); 

    fprintf(stdout, "Reading\n"); 
    fflush(stdout); 

    char sbuf[8192]; 
    if (!fgets(sbuf, sizeof(sbuf), stdin)) { 
     fprintf(stdout, "EOF\n"); 
     fflush(stdout); 
     QCoreApplication::exit(); 
     return; 
    } 

    emit sigOutputData(QString::fromUtf8(sbuf)); 

    notifier->setEnabled(true); 
    } 

private: 
    QSocketNotifier* notifier; 
}; 

예 주()

int main(int argc, char *argv[]) 
{ 
    QCoreApplication a(argc, argv); 
    new StdinReader(&a); 
    return a.exec(); 
}