PDA

View Full Version : QAbstractSocket::waitForBytesWritten() is not allowed in UnconnectedState



liam0connor
8th May 2019, 10:45
Im having trouble with my telnet connection by TCP where i need to enter the initials twice as the server needs this (not my server) but then when i have the initials entered once and are about to type them in the second time it seems like im getting thrown off
this is the code when i push a button it needs to connect by TCP to a ip entered in the GUI
IMPORTANT when i try and connect to the server with putty it works fine


void MainWindow::on_reboot_clicked()
{
QString hostName = ui->hostName->text();
int port = ui->Port->text().toInt();

socket = new QTcpSocket(this);

//connection
socket->connectToHost(hostName, port, QIODevice::ReadWrite);

if(socket->waitForConnected(300)){//if succesfull connection run this
qDebug() << "connected";

//sending initials first time
socket->write("admin\r\n");
socket->waitForReadyRead(10);
qDebug() << "reading first" << socket->readAll();
socket->waitForBytesWritten(10);
//socket->waitForReadyRead(10);
socket->write("Admin1\r\n");
socket->waitForReadyRead(10);
socket->waitForBytesWritten(10);
//socket->waitForReadyRead(10);
qDebug() << "reading second" << socket->readAll();

//sending initials second time
socket->write("admin\r\n");
socket->waitForReadyRead(10);
socket->waitForBytesWritten(10);
//socket->waitForReadyRead(10);
qDebug() << "reading third" << socket->readAll();
socket->write("Admin1\r\n");
socket->waitForReadyRead(10);
socket->waitForBytesWritten(10);
//socket->waitForReadyRead(10);
qDebug() << "reading fourth" << socket->readAll();

//reboot command
socket->write("reboot\r\n");
socket->waitForBytesWritten(2000); // waiting the 2 seconds for the reboot command to take effect

qDebug() << "done";
//closing connection
socket->close();

}
else {//if the program couldn't connect the program will output this in debug terminal
qDebug() << "not connected";

}
}


Here is what i am getting on the output terminal

connected
reading first "\xFF\xFB\x01"
reading second "\xFF\xFB\x03"
QAbstractSocket::waitForBytesWritten() is not allowed in UnconnectedState
reading third ""
QAbstractSocket::waitForBytesWritten() is not allowed in UnconnectedState
reading fourth ""
QAbstractSocket::waitForBytesWritten() is not allowed in UnconnectedState
done

and i just can't seem to figure out what is wrong

anda_skoa
8th May 2019, 14:14
Well, given the error messages it seems the socket has disconnected at some point.

Aside from blocking I/O in a GUI not being a good idea, why do you wait for write after waiting for read?
Would it make more sense either just wait for the response or wait for sending before waiting for the response?

You also never check the return values of these waits.

Cheers,
_

liam0connor
9th May 2019, 14:49
Well, given the error messages it seems the socket has disconnected at some point.

Aside from blocking I/O in a GUI not being a good idea, why do you wait for write after waiting for read?
Would it make more sense either just wait for the response or wait for sending before waiting for the response?

You also never check the return values of these waits.

Cheers,
_

yeah i can see what you mean that was an error i have changed it now so that i wait for bytes written first and then wait for a ready read and i might sound like a newbie but what response would i get from the the waits?
And do you have any idea as to how i could change to code to maybe try non blocking communication

my code as of now


void MainWindow::on_reboot_clicked()
{
QString hostName = ui->hostName->text();
int port = ui->Port->text().toInt();

socket = new QTcpSocket(this);

//connection
socket->connectToHost(hostName, port, QIODevice::ReadWrite);

if(socket->waitForConnected(300)){//if succesfull connection run this
qDebug() << "connected";

//sending initials first time
socket->write("admin");
socket->waitForBytesWritten(10);
socket->waitForReadyRead(10);
qDebug() << "reading first" << socket->readAll();
socket->write("Admin1");
socket->waitForBytesWritten(10);
socket->waitForReadyRead(10);
qDebug() << "reading second" << socket->readAll();

//reboot command
socket->write("reboot");
socket->waitForBytesWritten(2000); // waiting the 2 seconds for the reboot command to take effect

qDebug() << "done";
//closing connection
socket->close();

}
else {//if the program couldn't connect the program will output this in debug terminal
qDebug() << "not connected";

}
}

anda_skoa
10th May 2019, 08:17
i might sound like a newbie but what response would i get from the the waits?

The waitForXYZ methods return true if the signal has been emitted or false if that was not the case.



And do you have any idea as to how i could change to code to maybe try non blocking communication

By connecting to the signals instead of using the waitFor methods.

Usually the pattern is a "Command" or "Job", an object that encapsulates the steps necessary to achieve the goal.

Something like


class RebootCommand : public QObject
{
Q_OBJECT
public:
explicit RebootCommand(QObject *parent = nullptr);

void start(const QString &host, int port);

signals:
void finished();

private slots:
void onConnected();
void onReadyRead();

private:
enum State {
Disconnected,
WaitingForUserPrompt1,
WaitingForPasswordPrompt1,
WaitingForUserPrompt2,
WaitingForPasswordPrompt2
};
State m_state = Disconnected;

QTcpSocket *m_socket = nullptr;
};


Cheers,
_