Seite 1 von 1

Problem bei der Netzwerkkommunikation

Verfasst: 25. Februar 2009 17:01
von STS301
hi

Ich schreibe gerade ein kleines Chatprogramm, habe aber ein Problem mit dem Server.
Ich habe mir zwar das loopback Example angesehen, hat mich aber nicht wirklich weitergebracht, da ich etwas anderes strukturiert habe.

Code: Alles auswählen

/* im Start */
ui->setupUi(this);
    server = new QTcpServer();

    connect(server,SIGNAL(newConnection()),
        this,SLOT(incomingConnection()));

    server->listen(QHostAddress::Any, 13000);

void QNetShare::readyRead()
{
    QTcpSocket *socket = (QTcpSocket*)QObject::sender();
    if (!socket)
        return;
    QString msg = QString::fromLocal8Bit(socket->readAll());
    QMessageBox msgBox;
    msgBox.setText(tr("%1").arg(msg));
    msgBox.exec();
    socket->close();
    socket = 0;
    delete socket;
}

void QNetShare::incomingConnection()
 {
    qDebug("incoming");
    serversock = server->nextPendingConnection();
    connect(serversock, SIGNAL(readyRead()),
             this, SLOT(readReady()));
    serversock->waitForBytesWritten(5000);
    serversock->disconnectFromHost();
    serversock = 0;
    delete serversock;
  //   serverStatusLabel->setText(tr("Accepted connection"));
     //server.close();
 }

void QNetShare::on_btn_send_clicked()
{
    newConnection();
}

void QNetShare::newConnection()
{
    /*if (ui->edt_targetIP->text().isEmpty())
        return;  ist unter Kommentar, da ich zur Zeit noch mit Localhost arbeite*/

    if (socket) {
        socket->abort();
        socket = 0;
        delete socket;
    }

    QTcpSocket *socket;
    socket = new QTcpSocket();
    connect(socket,SIGNAL(readyRead()),this,SLOT(readyRead()));
    connect(socket,SIGNAL(error(QAbstractSocket::SocketError)),
    this,SLOT(socketError(QAbstractSocket::SocketError)));

    socket->connectToHost(/* ui->edt_targetIP->text() */ QHostAddress::LocalHost, 13000);
   socket->write("Hallo");
}
Im Anhang ist das ganze Projekt nocheinmal.

Er bricht beim senden einfach ab.
Ich habe es im qt creator geschrieben

Verfasst: 25. Februar 2009 19:25
von solarix
void QNetShare::incomingConnection() :

Code: Alles auswählen

serversock = server->nextPendingConnection();
    connect(serversock, SIGNAL(readyRead()),
             this, SLOT(readReady()));
    serversock->waitForBytesWritten(5000);
    serversock->disconnectFromHost();
    serversock = 0;
    delete serversock; 
Warum "waitForBytesWritten"? Du schreibst ja gar nichts auf den Socket, worauf willst du also warten?

Warum fragst du dich, weshalb du keine Daten bekommst, wenn du gleich nach der Verbindungsaufnahme wieder mit "disconnectFromHost()" abbrichst?

Warum "serversock = 0" und "delete serversock"? Was genau soll denn das Löschen eines NULL-Pointers bewirken?

Da gibt's aber noch viel mehr..

Code: Alles auswählen

if (socket) {
        socket->abort();
        socket = 0;
        delete socket;
}
Das ergibt dann ein Speicherleck...

und

Code: Alles auswählen

QTcpSocket *socket;
hier gibt's ne lokale Variabel, die gleich heisst wie eine private Membervariabel..

Verfasst: 25. Februar 2009 19:43
von STS301
danke für deine Antwort.

Ich habe recht oft im Internet gesucht und da hat sich, wie ich vermutet hatte, ein haufen Müll zusammengebraut.

gut, habe jetzt die von dir angesprochenen Fehler geändert.

gibt es eigentlich eine Abfrage, wie ich festellen kann, ob die zwei Programme jetzt verbunden sind?

also so wie

Code: Alles auswählen

if (socket->connected == true) ...
oder wie sollte ich es sonst machen, weil jetzt versucht er zu verbinden und schreibt gleich, also kann der Server gar nichts empfangen.
mit dem Timeout habe ich es mir auch schon überlegt, aber das finde ich ist nicht die optimale Lösung.

Verfasst: 25. Februar 2009 19:53
von solarix
gibt es eigentlich eine Abfrage, wie ich festellen kann, ob die zwei Programme jetzt verbunden sind?
Selbstverständlich... schau mal die Methoden des Sockets durch:
http://doc.trolltech.com/4.4/qabstractsocket.html

Aber besser wäre nicht den Zustand (...!) abzufragen, sondern auf die Verbindung zu warten.. (Signal/Slot).. schau dir dazu mal die Signals in der obigen Doku an...

Verfasst: 25. Februar 2009 20:01
von STS301
danke, ich denke mal du willst auf die Abfrage waitForConnected(5000) hinaus, nur was ist wenn er nicht verbunden ist?

bei dem code

Code: Alles auswählen

socket->connectToHost(QHostAddress::LocalHost, 13000);
socket->waitForConnected(5000);
socket->write("Hallo");

Verfasst: 25. Februar 2009 20:48
von solarix
nur was ist wenn er nicht verbunden ist?
Kleiner Tipp: in der Doku ist der Rückgabe bestens beschrieben....
ich denke mal du willst auf die Abfrage waitForConnected(5000)
Eigentlich nicht... ich würde möglichst auf blockierende Operationen verzichten. Ich wollte eher auf das Signal "connected()" hinweisen...

Verfasst: 25. Februar 2009 21:03
von STS301
ja schon, nur soll ich es dann als abfrage darstellen, oder funktioniert das so auch

Code: Alles auswählen


socket->connectToHost(QHostAddress::LocalHost, 13000);
socket->connected();
socket->write("Hallo"); 

Verfasst: 25. Februar 2009 22:17
von solarix
eben _nicht_ blockierend... du schreibst ja selbst:

Code: Alles auswählen

connect(socket,SIGNAL(error(QAbstractSocket::SocketError)),
    this,SLOT(socketError(QAbstractSocket::SocketError))); 
Da kannst du ja auch gleich noch ein eigener Slot mit "connected()" verbinden... dann musst du nicht warten, sondern dann wird bei einer erfolgreichen Verbindung ja dein Slot aufgerufen, in welchem du dann "was-auch-immer" versenden kannst..

Verfasst: 26. Februar 2009 08:02
von STS301
gut, danke für deine Hilfe, melde mich wieder, wenn ich ein Problem habe

Verfasst: 2. März 2009 15:19
von STS301
hi

habe diesmal wieder ein Problem

der Client kann mit dem Server nicht connecten (sagt zumindest die Fehlermeldung:

Code: Alles auswählen

 QObject::connect: Cannot connect (null)::readyRead() to QNetShare::readReady()
)

ich hänge einmal das Projekt wieder an, hier aber ein paar Zeilen, wo ich glaube, dass hier das Problem vergraben ist und dann im newconnection habe ich das Connected eingebaut bin mir nicht sicher, ob ichs richtig gemacht habe)

Code: Alles auswählen

void QNetShare::incomingConnection()
 {
    qDebug("incoming");
    serversock = server->nextPendingConnection();
    connect(serversock, SIGNAL(readyRead()),
             this, SLOT(readReady()));
 }

void QNetShare::readyRead()
{
    QTcpSocket *tcpsocket = (QTcpSocket*)QObject::sender();
    if (!tcpsocket)
        return;
    QString msg = QString::fromLocal8Bit(socket->readAll());
    ui->lbl_fromserver->setText(msg);
    tcpsocket->close();
}

void QNetShare::newConnection()
{
    /*if (ui->edt_targetIP->text().isEmpty())
        return; */

    QTcpSocket *socket;
    socket = new QTcpSocket();
    connect(socket,SIGNAL(readyRead()),this,SLOT(readyRead()));
    connect(socket,SIGNAL(error(QAbstractSocket::SocketError)),
    this,SLOT(socketError(QAbstractSocket::SocketError)));

    socket->connectToHost(/* ui->edt_targetIP->text() */ QHostAddress::LocalHost, 13000);
    connect(socket, SIGNAL(connected()), this, SLOT(sendmessage()));
}

void QNetShare::sendmessage()
{
    socket->write(ui->edt_message->toPlainText().toLocal8Bit());
}

Verfasst: 2. März 2009 18:08
von Strahlex
Kann ja gar net funktionieren, achte auf den Tippfehler im Connect ReadReady stat ReadyRead. :wink:

Verfasst: 2. März 2009 18:41
von STS301
das alleine hat den Fehler leider auch nicht behoben

Verfasst: 4. März 2009 13:46
von STS301
hat keiner eine Idee?