Seite 1 von 2

Problem mit QTcpSocket

Verfasst: 29. Januar 2007 11:11
von SuperSonik
Hallo Leute,
ich habe ein Problem mit QTcpSocket.
Den Verbindungsaufbau habe ich anscheinend hinbekommen, aber dann läuft das Ganze in eine Fehlermeldung. :(
Hier erstmal mein Quellcode:

Code: Alles auswählen

void connectToServer(void){
pushButton_abfragen->setText(tr("Abfragen 2......"));
tcpsocket.connectToHost(lineEdit_ipgypsy->text(),5050);
pushButton_abfragen->setText(tr("Abfragen ......"));
pushButton_upload->setEnabled(false);
pushButton_abfragen->setEnabled(false);    		
 
};//connectToServer

void  sendRequest(void){

QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_4_2);
QString abfrage("SELECT * FROM Historie; \r\n");


out << quint16(0) << abfrage.toAscii();
out.device()->seek(0);
out << quint16(block.size() - sizeof(quint16));
tcpsocket.write(block);
pushButton_abfragen->setText(tcpsocket.errorString());

};//sendRequest 

void  getData(void){
	pushButton_abfragen->setText(tr("Abfragen 2......"));
	pushButton_abfragen->setText(tcpsocket.errorString()+"   --1");
	
   	QFile confdatei("testdata.txt");
   	confdatei.open(QIODevice::WriteOnly);
   	QDataStream conf(&confdatei);
 	QByteArray ip,wert,datum;
    conf.setVersion(QDataStream::Qt_4_2);
    
	//pushButton_abfragen->setText(tcpsocket.errorString()+"   --2");    
	
     QDataStream in(&tcpsocket);
     in.setVersion(QDataStream::Qt_4_2);
     
 	//pushButton_abfragen->setText(tcpsocket.errorString()+"   --3");
     
     forever{
     	
     if(nextBlockSize == 0){
     if(tcpsocket.bytesAvailable() < sizeof(quint16)){ break; }
     	in >> nextBlockSize;	
     }	
     if(nextBlockSize == 0xFFFF){
     	closeConnection();
   		break;  	
     }
     if(tcpsocket.bytesAvailable() < nextBlockSize){ break;}
     
    conf << tcpsocket.readAll();//ip << wert << datum;
    
     
     	nextBlockSize = 0;
     }


 	
	
     
};//getData

void  closeConnection(void){

tcpsocket.close();
pushButton_abfragen->setText(tr("Daten abfragen"));
pushButton_upload->setEnabled(true);
pushButton_abfragen->setEnabled(true);   

};//closeConnection

void displayError(QAbstractSocket::SocketError socketError)
 {
     switch (socketError) {
     case QAbstractSocket::RemoteHostClosedError:
         break;
     case QAbstractSocket::HostNotFoundError:
         QMessageBox::information(this, tr("Fortune Client"),
                                  tr("The host was not found. Please check the "
                                     "host name and port settings."));
         pushButton_abfragen->setText(tr("Daten abfragen"));
		 pushButton_upload->setEnabled(true);
		 pushButton_abfragen->setEnabled(true);
         break;
     case QAbstractSocket::ConnectionRefusedError:
         QMessageBox::information(this, tr("Fortune Client"),
                                  tr("The connection was refused by the peer. "
                                     "Make sure the fortune server is running, "
                                     "and check that the host name and port "
                                     "settings are correct."));
         pushButton_abfragen->setText(tr("Daten abfragen"));
         pushButton_upload->setEnabled(true);
         pushButton_abfragen->setEnabled(true);
         break;
     default:
         QMessageBox::information(this, tr("Fortune Client"),
                                  tr("The following error occurred: %1.")
                                  .arg(tcpsocket.errorString()));
         pushButton_abfragen->setText(tr("Daten abfragen"));
		 pushButton_upload->setEnabled(true);
		 pushButton_abfragen->setEnabled(true);
     }

     
 }
Die Funktionen sind alle public slots und nextBlockSize und tcpsocket sind Membervariablen.
Die entsprechenden connect Aufrufe habe ich auch gemacht.
An der Stelle

Code: Alles auswählen

 pushButton_abfragen->setText(tcpsocket.errorString()+"   --1");
bekomme ich dann immer die Meldung "Unknown error". :?
Kann mir jemand sagen was ich falsch mache?
Gruß,
SuperSonik

neue Erkenntnisse

Verfasst: 30. Januar 2007 12:16
von SuperSonik
Hallo,
ich nochmal.
Ich bin mittlerweile der Meinung das der Fehler an dem QString beim senden liegen muß:

Code: Alles auswählen

QString abfrage("SELECT * FROM Datum; \r\n");
Vielleicht liegt's irgendwie an dem \r\n aber wenn ich die weg lasse bekomme ich direkt einen
Fehler. \0 habe ich auch schon versucht.
Die Verbindung wird sofort geschlossen, ohne das ich Daten gesendet bekomme.
Sprich auf das Senden der Anfrage wird als Antwort das disconnected() Signal ausgelöst.
Hat jemand eine Ahnung? Ich bin auch schon dankbar für Tipps, was ich noch versuchen könnte.
Gruß,
SuperSonik

Verfasst: 31. Januar 2007 09:06
von Gara
Hallo!

Ein Schuss ins Blaue: Hast Du mal versucht, den Backslash doppelt zu setzen? Also "\\r\\n"?

Irgendwo hatte ich da mal Streß mit und hab ewig gebraucht, um das zu finden. Nur weiß ich leider nicht mehr, ob das auch mit QString zusammenhing.

Verfasst: 31. Januar 2007 09:34
von Christian81
Wenn man den Code etwas vereinfachen könnte, würde ich ihn ja mal debuggen, aber so ist es sehr unübersichtlich.
-> Code soweit vereinfachen bis man nur noch das Problem sieht.

Verfasst: 31. Januar 2007 10:44
von SuperSonik
Christian81 hat geschrieben:Wenn man den Code etwas vereinfachen könnte, würde ich ihn ja mal debuggen, aber so ist es sehr unübersichtlich.
-> Code soweit vereinfachen bis man nur noch das Problem sieht.
Hi,
das Problem steckt in diesem Slot:

Code: Alles auswählen

void  sendRequest(void){

QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_4_2);
QString abfrage("SELECT * FROM Historie; \r\n");


out << quint16(0) << abfrage.toAscii();
out.device()->seek(0);
out << quint16(block.size() - sizeof(quint16));
tcpsocket.write(block);
pushButton_abfragen->setText(tcpsocket.errorString());

};//sendRequest

 
Den Rest habe ich nur mit abgebildet damit man sich ein Gesammtbild
machen kann.
Gruß,
SuperSonik

Verfasst: 31. Januar 2007 10:57
von SuperSonik
Gara hat geschrieben:Hallo!

Ein Schuss ins Blaue: Hast Du mal versucht, den Backslash doppelt zu setzen? Also "\\r\\n"?

Irgendwo hatte ich da mal Streß mit und hab ewig gebraucht, um das zu finden. Nur weiß ich leider nicht mehr, ob das auch mit QString zusammenhing.
Ich hab das mal versucht. Aber daran liegt's nicht. - leider
Aber auf die Idee wäre ich jetzt nicht gekommen. - danke trotzdem
Gruß,

SuperSonik

Verfasst: 31. Januar 2007 10:59
von Christian81
Ok, einfach mal probiert puren Text zu schicken? Also ohne QString und den anderen Zeugs? Kommt es auf der Gegenseite an?

Verfasst: 31. Januar 2007 11:18
von SuperSonik
Christian81 hat geschrieben:Ok, einfach mal probiert puren Text zu schicken? Also ohne QString und den anderen Zeugs? Kommt es auf der Gegenseite an?
Puren Text schicken? Das ist ja das was ich versuche.
Ich würde gerne über Tcp exakt den String "SELECT * FROM Historie; \r\n"
schicken. So das die Gegenseite genau diesen String erhält.
Allerdings würde ich gerne bei Qt bleiben also nicht irgendwie mit MFC oder sonstwas mischen.
Christian81 hat geschrieben: Kommt es auf der Gegenseite an?
Ich habe allerdings keine Möglichkeit nachzuschauen was auf der Gegenseite
ankommt. Ich kann nur aus der Reaktion schließen was ankamm.
Die Gegenseite ist ein Datenlogger, also ein kleiner embedded Pc auf der Basis von Windows CE.
Gruß,
SuperSonik

Verfasst: 31. Januar 2007 11:22
von Christian81
Und was gibts da für ein Problem? Warum benutzt Du dann QDatastream?

tcpsocket.,write(QByteArray("wasauchimmer"));

Verfasst: 31. Januar 2007 11:26
von SuperSonik
Christian81 hat geschrieben:Und was gibts da für ein Problem? Warum benutzt Du dann QDatastream?

tcpsocket.,write(QByteArray("wasauchimmer"));

Keine Ahnung ich habe die Vorlage wie man sowas machen sollte aus nem Buch über Qt. Bisher habe ich mir mit Qt immer nur ein paar GUIs zusammen gestrickt. Ich bin nicht wirklich ein Experte. :oops: Naja jeder hat mal klein angefangen.
Gruß,
SuperSonik

Verfasst: 31. Januar 2007 11:29
von Christian81
Mit QDataStream sollte es natürlich auch gehen, aber für den Anfang und wenn man weiss was man schickt ist es so wesentlich besser. Allerdings verstehe ich die 'out << quint16(0) ' überhaupt nicht...

Verfasst: 31. Januar 2007 11:33
von SuperSonik
Ok,
ich hab's mal ausprobiert.

Ich habe denn kompletten Code aus dem sendRequest Slot
durch deine Zeile ersetzt. Natürlich mit meinem String.
Das Ergebnis ist allerdings das Selbe. Als Antwort auf meine Anfrage wird
zunächst das readyRead() Signal ausgelöst und danach sofort das disconnected() Signal. Ohne das ich eine Fehlermeldung über das error(QAbstractSocket::SocketError) Signal erhalten würde.
Gruß,
Sonik

Verfasst: 31. Januar 2007 11:37
von Christian81
Wo meinst Du jetzt? Auf der Gegenseite? Was wird dort gelesen? Ist es Dein String?

Verfasst: 31. Januar 2007 11:50
von SuperSonik
Christian81 hat geschrieben:Wo meinst Du jetzt? Auf der Gegenseite? Was wird dort gelesen? Ist es Dein String?
Nein nicht auf der Gegenseite. In meiner Anwendung. An die Gegenseite komme ich nicht ran. Das ist ein kleiner Datenlogger mit einer TinySql Datenank.
'out << quint16(0) ' usw. hat laut dem Buch aus dem ich das habe folgende Funktion:
Ich muß an den Anfang meines Tcp Paketes die Größe des Paketes schreiben. Und zwar als quint16. Also schreibe ich zuerst das nötige Feld
an den Anfang, dann die Nachricht und dann springe ich zurück an den Anfang (out.device()->seek(0)) und schreibe dann die richtige Größe rein.
Gruß,
Sonik

Verfasst: 31. Januar 2007 12:05
von Christian81
Ok, langsam verstehe ich was Du machst.
Ich würde sagen dass die Gegenstelle die Verbindung schließt sobald etwas falsches ankommt. D.h. Du schickst was falsches :)
Den Aufbau deiner Daten hast du ja jetzt beschrieben. Was allerdings falsch ist, ist die Verwendung von QDataStream. QDataStream schreibt die Daten nicht einfach so in das QIODevice, sondern speichert sie Platformunabhängig (siehe Doku). D.h. Es werden noch Zusatzinfos gepspeichert um die Daten später wieder auslesen zu können -> die Daten werden also nicht in dem Format gesendet das Du möchtest.
Ich würde deshalb direkt in das QByteArray mittels QBuffer schreiben.

Code: Alles auswählen

QByteArray ba;
QBuffer buf(&ba);
QByteArray sql("Select wasauchimmer");
quint16 len = sql.length();

buf.write(&len, sizeof(quint16));
buf.write(sql);
Und dann ab damit. Allerdings solltest Du noch klären ob die Länge als Little oder BigEndian gesendet werden muss.