2010-10-24 5 views
2

J'essaye de connecter un serveur "hello world" tordu très basique avec un client Qt tcp basique.Client QT C++ tcp avec serveur python tordu

Le client utilise ces signaux:

connect(&socket, SIGNAL(connected()), this, SLOT(startTransfer())); 
connect(&socket, SIGNAL(readyRead()), this, SLOT(readServer())); 

puis readServer() ressemble à ceci:

ui->resultLabel->setText("Reading.."); 
QDataStream in(&socket); 
//in.setVersion(QT_4_0); 

if (blockSize == 0) { 
    if (socket.bytesAvailable() < (int)sizeof(quint16)) 
     return; 

    in >> blockSize; 
} 

if (socket.bytesAvailable() < blockSize) 
    return; 

QString theResult; 
in >> theResult; 
qDebug() << in; 
qDebug() << theResult; 
ui->resultLabel->setText(theResult); 

Le serveur J'utilise à des fins de test est simplement un exemple attrapé hors de son torsadés docs

from twisted.internet.protocol import Protocol, Factory 
from twisted.internet import reactor 

### Protocol Implementation 

# This is just about the simplest possible protocol 
class Echo(Protocol): 
    def dataReceived(self, data): 
     """ 
     As soon as any data is received, write it back. 
     """ 
     self.transport.write(data) 


def main(): 
    f = Factory() 
    f.protocol = Echo 
    reactor.listenTCP(8000, f) 
    reactor.run() 

if __name__ == '__main__': 
    main() 

readServer() s'appelle très bien, mais il ne semble jamais collec t l'une des données. J'ai lu quelque part que cela pourrait avoir à faire avec l'opérateur < < de QDataStream parce que Python ne l'envoie pas exactement en morceaux comme Qt attend. J'avoue que je ne suis pas très doué avec C++ ou Qt, mais l'idée du projet est d'écrire un client pour travailler avec un serveur torsadé existant, alors que le client peut être changé, je n'ai pas le choix mais pour le faire fonctionner avec ce serveur.

Merci d'avance pour toute aide.

Répondre

2

Le problème s'est avéré être QDataStream, qui est apparemment plus que juste un peu particulier sur les données qu'il lit. Heureusement, j'ai découvert QDataStream :: readRawData qui aimait beaucoup mieux les données envoyées par python (plus loin j'ai découvert que cela n'avait rien à voir avec twisted, mais l'implémentation du socket python lui-même.) Le code final ressemblait à ceci:

//use socket to construct a QDataStream object, like before 
QDataStream in(&socket); 
//in.setVersion(QDataStream::Qt_4_0); 
char buffer[1024] = {0}; 
//readRawData takes a char to dump to and the length, 
//so I'm sure there is a better way to do this. It worked for my example. 
in.readRawData(buffer, socket.bytesAvailable()); 
QString result; 
result = buffer; 
ui->resultLabel->setText(result); 
1

Une chose importante à comprendre à propos de TCP est qu'il ne s'agit pas d'un transport pour des messages (ou "morceaux") d'une taille particulière. C'est un transport pour un flux d'octets. Lorsque vous écrivez quelque chose comme:

if (socket.bytesAvailable() < (int)sizeof(quint16)) 
    return; 

alors vous feriez mieux d'avoir une boucle quelque part qui est d'invoquer ce code à nouveau, parce qu'il n'y a aucune garantie que la première fois que vous aurez tous les octets dont vous avez besoin pour franchir cette vérifier.

Vous n'avez pas partagé le code responsable de l'envoi de données au serveur d'écho, il est donc impossible de savoir réellement pourquoi votre client Qt n'obtient pas les données attendues, mais compte tenu de ce qui précède ne serait pas surpris s'il implique une mise en mémoire tampon incorrecte des données incomplètes.

Assurez-vous que si vous décidez de ne pas lire à partir de la socket car il n'y a pas suffisamment de données, essayez d'en relire plus tard, après l'arrivée de nouvelles données. Un bon moyen de le faire est de toujours lire les données dans un tampon d'application pour pouvoir utiliser select() ou epoll() ou que devez-vous dire quand il y a plus de données disponibles sur le socket. Ensuite, il suffit d'opérer sur le tampon de l'application.

+0

Merci, j'ai lu beaucoup à ce sujet et probablement besoin de lire plus. Comme je l'ai dit, c'est ma première tentative, et même si cela ne s'est pas avéré être le problème, je le garderai à l'esprit. – jsullivan88