2017-08-25 5 views
0

j'ai écrit un serveur TCP simple QT5 dont la tâche peut être simplifiée comme:Qt TCPSocket :: readyRead pas triggerd dans une situation particulière

  • écouter les connexions sur un port

  • après que quelqu'un s'y connecte, lire une chaîne à partir et puis imprimez la chaîne

  • fermer la prise et écouter de la prochaine connexion

Le code du serveur est comme ceci:

class Server:public QObject 
{ 
    Q_OBJECT 
public: 
    QTcpServer* TcpServer; 
    QTcpSocket* TcpSocket; 
    void Start(); 
public slots: 
    void OnConnection(); 
}; 


void Server::Start() 
{ 
    TcpServer = new QTcpServer(); 
    TcpServer->listen(QHostAddress::Any, 9999); 
    connect(TcpServer, &QTcpServer::newConnection, this, &Server::OnConnection); 
} 


void Server::OnConnection() 
{ 
    qDebug() << "connected"; 
    TcpSocket = TcpServer->nextPendingConnection(); 
    connect(TcpSocket, &QTcpSocket::readyRead, this, [=]() 
    { 
     qDebug() << "received:" << TcpSocket->readAll(); 
     TcpSocket->close(); 
    }); 
} 

Ensuite, j'ai cet extrait de code pour le client:

QTcpSocket socket; 
socket.connectToHost(QHostAddress::LocalHost, 9999); 
auto x = QString("Some information").toUtf8(); 
socket.write(x); 
socket.close(); 

Cet extrait de code fonctionne bien si je le lance seulement dans une application console , ou courir ici dans mon projet:

int main(int argc, char *argv[]) 
{ 
    QApplication a(argc, argv); 
    MainWindow w; // main window of my application 
    w.show(); 

    QTcpSocket socket; 
    socket.connectToHost(QHostAddress::LocalHost, 9999); 
    auto x = QString("Some information").toUtf8(); 
    socket.write(x); 
    socket.close(); 

    return a.exec(); 
} 

Voici la partie qui me rend confus:

Dans la fenêtre principale, il y a un QPushButton, son signal clicked est connecté à un slot, dans ce slot j'appellerai une fonction contenant l'extrait de code. La fonction s'occupe principalement de configurer la disposition de la fenêtre principale (j'ai utilisé QStackedWidget), et quand l'extrait de code est exécuté, cela fonctionne différemment. A partir du journal du serveur, je pense que le socket peut se connecter au serveur, mais le QTcpSocket::readyRead ne peut pas être déclenché, donc le serveur attend toujours les données, même si toutes les cinq lignes du fragment de code ont été exécutées (Dans le code que je fournis, le journal du serveur n'aura "connecté" que les données suivantes.)

Je ne sais pas pourquoi le QTcpSocket::readyRead du serveur ne peut pas être déclenché si je le mets dans cette fonction. . Quelqu'un peut-il l'expliquer?

Merci d'avoir lu ma question :-)

+0

Je pense que vous devriez ajouter l'appel de méthode http://doc.qt.io/qt-5/qiodevice.html#waitForBytesWritten avant de fermer le socket client. – Macias

Répondre

0

Lorsque vous écrivez l'application de la console, il est autorisé à utiliser votre extrait avec quelques modifications, parce que vous ne devez pas traiter avec une interface graphique de blocage. Il suffit d'utiliser les méthodes suivantes:
waitForConnected
waitForByttesWritten

Cependant, si vous écrivez un GUI vous shold utiliser des signaux.
Tout d'abord après avoir appelé connectToHost, attendez le signal connected . Ensuite, vous pouvez écrire vos données. Ensuite, attendez le signal bytesWritten et assurez-vous que le paramètre bytes est égal à la valeur renvoyée par la méthode write. Quand tout est OK, vous pouvez fermer la prise.