QTcpSocket / QTcpServer, connection closed
-
@KroMignon, thank you, for some reason I'm having some problems with the line:
clsSocketClient* pClient = new clsSocketClient(this);
no matching constructor for initialization of 'clsSocketClient', the header is present, I've even tried changing the constructor to expect QAbstractSocket*, still the same.
@SPlatten said in QTcpSocket / QTcpServer, connection closed:
no matching constructor for initialization of 'clsSocketClient', the header is present, I've even tried changing the constructor to expect QAbstractSocket*, still the same.
I don't know what
clsSocketClient
is.
I supposed it was:class clsSocketClient : public QTcpSocket { Q_OBJECT .... };
-
@SPlatten said in QTcpSocket / QTcpServer, connection closed:
no matching constructor for initialization of 'clsSocketClient', the header is present, I've even tried changing the constructor to expect QAbstractSocket*, still the same.
I don't know what
clsSocketClient
is.
I supposed it was:class clsSocketClient : public QTcpSocket { Q_OBJECT .... };
@KroMignon , clsSocketClient:
class clsSocketClient : public QTcpSocket { Q_OBJECT public: explicit clsSocketClient(QTcpSocket* pClient = nullptr); ...
Implementation:
clsSocketClient::clsSocketClient(QTcpSocket* pClient) : QTcpSocket(pClient) { QObject::connect(this, &QTcpSocket::connected, this, &clsSocketClient::onConnected); QObject::connect(this, &QTcpSocket::bytesWritten, this, &clsSocketClient::onBytesWritten); QObject::connect(this, &QTcpSocket::disconnected, this, &QObject::deleteLater); QObject::connect(this, &QTcpSocket::disconnected, this, &clsSocketClient::onDisconnected); QObject::connect(this, &QTcpSocket::errorOccurred, this, &clsSocketClient::onErrorOccurred); QObject::connect(this, &QTcpSocket::readyRead, this, &clsSocketClient::onDataIn); QObject::connect(this, &QTcpSocket::stateChanged, this, &clsSocketClient::onStateChanged); }
-
@KroMignon , clsSocketClient:
class clsSocketClient : public QTcpSocket { Q_OBJECT public: explicit clsSocketClient(QTcpSocket* pClient = nullptr); ...
Implementation:
clsSocketClient::clsSocketClient(QTcpSocket* pClient) : QTcpSocket(pClient) { QObject::connect(this, &QTcpSocket::connected, this, &clsSocketClient::onConnected); QObject::connect(this, &QTcpSocket::bytesWritten, this, &clsSocketClient::onBytesWritten); QObject::connect(this, &QTcpSocket::disconnected, this, &QObject::deleteLater); QObject::connect(this, &QTcpSocket::disconnected, this, &clsSocketClient::onDisconnected); QObject::connect(this, &QTcpSocket::errorOccurred, this, &clsSocketClient::onErrorOccurred); QObject::connect(this, &QTcpSocket::readyRead, this, &clsSocketClient::onDataIn); QObject::connect(this, &QTcpSocket::stateChanged, this, &clsSocketClient::onStateChanged); }
@SPlatten said in QTcpSocket / QTcpServer, connection closed:
explicit clsSocketClient(QTcpSocket* pClient = nullptr);
I guess "this" is not QTcpSocket right? So, how can that work?
-
@jsulm , this is instance of clsSocketServer which is:
class clsSocketServer : public QTcpServer { Q_OBJECT ...
As I said I tried changing the clsSocketClient to accept QAbstractSocket* but still the same, aren't QTcpServer and QTcpSocket both based on QAbstractSocket ?
-
@jsulm , this is instance of clsSocketServer which is:
class clsSocketServer : public QTcpServer { Q_OBJECT ...
As I said I tried changing the clsSocketClient to accept QAbstractSocket* but still the same, aren't QTcpServer and QTcpSocket both based on QAbstractSocket ?
-
@SPlatten I'm reffering to this:
clsSocketClient* pClient = new clsSocketClient(this);
What is "this" here? If it is not QTcpSocket then it can't work!
-
@jsulm ,@KroMignon , sorted, it's now working and communicating, thank you:
void clsSocketServer::incomingConnection(qintptr sfd) { clsSocketClient* pClient = new clsSocketClient(new QTcpSocket()); pClient->setSocketDescriptor(sfd); addPendingConnection(pClient); }
-
@KroMignon , clsSocketClient:
class clsSocketClient : public QTcpSocket { Q_OBJECT public: explicit clsSocketClient(QTcpSocket* pClient = nullptr); ...
Implementation:
clsSocketClient::clsSocketClient(QTcpSocket* pClient) : QTcpSocket(pClient) { QObject::connect(this, &QTcpSocket::connected, this, &clsSocketClient::onConnected); QObject::connect(this, &QTcpSocket::bytesWritten, this, &clsSocketClient::onBytesWritten); QObject::connect(this, &QTcpSocket::disconnected, this, &QObject::deleteLater); QObject::connect(this, &QTcpSocket::disconnected, this, &clsSocketClient::onDisconnected); QObject::connect(this, &QTcpSocket::errorOccurred, this, &clsSocketClient::onErrorOccurred); QObject::connect(this, &QTcpSocket::readyRead, this, &clsSocketClient::onDataIn); QObject::connect(this, &QTcpSocket::stateChanged, this, &clsSocketClient::onStateChanged); }
@SPlatten said in QTcpSocket / QTcpServer, connection closed:
class clsSocketClient : public QTcpSocket {
Q_OBJECTpublic: explicit clsSocketClient(QTcpSocket* pClient = nullptr);
...
Please change this to:
class clsSocketClient : public QTcpSocket { Q_OBJECT public: explicit clsSocketClient(QObject *parent = nullptr);
-
This post is deleted!
-
@jsulm ,@KroMignon , sorted, it's now working and communicating, thank you:
void clsSocketServer::incomingConnection(qintptr sfd) { clsSocketClient* pClient = new clsSocketClient(new QTcpSocket()); pClient->setSocketDescriptor(sfd); addPendingConnection(pClient); }
@SPlatten said in QTcpSocket / QTcpServer, connection closed:
void clsSocketServer::incomingConnection(qintptr sfd) {
clsSocketClient* pClient = new clsSocketClient(new QTcpSocket());
pClient->setSocketDescriptor(sfd);
addPendingConnection(pClient);
}Why to you do this?
clsSocketClient* pClient = new clsSocketClient(new QTcpSocket());
is an nonsense! -
@SPlatten said in QTcpSocket / QTcpServer, connection closed:
which is derived from QTcpServer
QTcpServer != QTcpSocket
-
@SPlatten said in QTcpSocket / QTcpServer, connection closed:
void clsSocketServer::incomingConnection(qintptr sfd) {
clsSocketClient* pClient = new clsSocketClient(new QTcpSocket());
pClient->setSocketDescriptor(sfd);
addPendingConnection(pClient);
}Why to you do this?
clsSocketClient* pClient = new clsSocketClient(new QTcpSocket());
is an nonsense!@KroMignon It compiles and works, I tried several other things that don't.
-
@KroMignon It compiles and works, I tried several other things that don't.
@SPlatten said in QTcpSocket / QTcpServer, connection closed:
It compiles and works
Doesn't change the fact that it is nonsense.
Do it the way @KroMignon shown you. -
@SPlatten said in QTcpSocket / QTcpServer, connection closed:
It compiles and works
Doesn't change the fact that it is nonsense.
Do it the way @KroMignon shown you. -
@jsulm , @KroMignon , changed and compiled, still working :)
@SPlatten said in QTcpSocket / QTcpServer, connection closed:
changed and compiled, still working :)
It is really disappointing that you don't try to understand what you are doing wrong.
This give the bad taste that you are just placing code together but not have a clue what you are doing.The class constructor
QTcpSocket(QObject *parent)
is used to define the parent object to this instance.
Parent is used, in Qt, to handle automatic instance cleanup when parent instance is destroyed.
This simplify also threading, moving parent instance to a thread will also moves all his "childrens".Please, please, read a little bit of Qt documentation to understand what you are doing.
By doing
clsSocketClient* pClient = new clsSocketClient(new QTcpSocket());
you a creating a class which will have a parent QObject, but for what?And the QTcpSocket instance you have created will never be deleted!!!
This not clean programming!
-
@KroMignon , What I'm struggling to get to grips with is getting the QTcpServer and QTcpSocket to work. I'm using the examples to prod and learn. I have written lots of socket based applications in the past, not Qt.
I am an experience programmer, the samples FortuneServer and FortuneClient do not use incomingConnection directly either, they are very lean examples. The examples to not call addPendingConnection either.
Initialisation of QTcpServer in FortuneServer:
tcpServer = new QTcpServer(this); if (!tcpServer->listen()) { QMessageBox::critical(this, tr("Fortune Server"), tr("Unable to start the server: %1.") .arg(tcpServer->errorString())); close(); return; } //! [0] QString ipAddress; QList<QHostAddress> ipAddressesList = QNetworkInterface::allAddresses(); // use the first non-localhost IPv4 address for (int i = 0; i < ipAddressesList.size(); ++i) { if (ipAddressesList.at(i) != QHostAddress::LocalHost && ipAddressesList.at(i).toIPv4Address()) { ipAddress = ipAddressesList.at(i).toString(); break; } } // if we did not find one, use IPv4 localhost if (ipAddress.isEmpty()) ipAddress = QHostAddress(QHostAddress::LocalHost).toString(); statusLabel->setText(tr("The server is running on\n\nIP: %1\nport: %2\n\n" "Run the Fortune Client example now.") .arg(ipAddress).arg(tcpServer->serverPort()));
The slot that is connected to the newConnection signal:
void Server::sendFortune() { QByteArray block; QDataStream out(&block, QIODevice::WriteOnly); out.setVersion(QDataStream::Qt_5_10); out << fortunes[QRandomGenerator::global()->bounded(fortunes.size())]; QTcpSocket *clientConnection = tcpServer->nextPendingConnection(); qDebug() << "Server::sendFortune clientConnection->isOpen(): " << clientConnection->isOpen(); qDebug() << "Server::sendFortune clientConnection->error(): " << clientConnection->error(); connect(clientConnection, &QAbstractSocket::disconnected, clientConnection, &QObject::deleteLater); clientConnection->write(block); clientConnection->disconnectFromHost(); }
The FortuneClient doesn't use addPendingConnection either.
In my application newConnection is getting called, I've said this before. Its sending data successfully that I'm now looking at as this isn't happening.
@SPlatten said in QTcpSocket / QTcpServer, connection closed:
the samples FortuneServer and FortuneClient do not use incomingConnection directly either, they are very lean examples. The examples to not call addPendingConnection either.
The important difference here is that the FortuneServer example does not subclass QTcpServer or QTcpSocket. When you subclass it and reimplement functions, there are more gotchas to watch out for.
Your program looks quite complex; I suggest you start by implementing a simple "lean" program from scratch first (without subclassing) and make sure that works. After that, you can gradually add the extra features that you want.
-
@SPlatten said in QTcpSocket / QTcpServer, connection closed:
changed and compiled, still working :)
It is really disappointing that you don't try to understand what you are doing wrong.
This give the bad taste that you are just placing code together but not have a clue what you are doing.The class constructor
QTcpSocket(QObject *parent)
is used to define the parent object to this instance.
Parent is used, in Qt, to handle automatic instance cleanup when parent instance is destroyed.
This simplify also threading, moving parent instance to a thread will also moves all his "childrens".Please, please, read a little bit of Qt documentation to understand what you are doing.
By doing
clsSocketClient* pClient = new clsSocketClient(new QTcpSocket());
you a creating a class which will have a parent QObject, but for what?And the QTcpSocket instance you have created will never be deleted!!!
This not clean programming!
@KroMignon , How can you possibly know what I'm trying to do, of course I want to understand it.
The issue is I have such a lot of work ahead of me that I just don't have the luxury of spending hours on one particular problem.
-
@SPlatten said in QTcpSocket / QTcpServer, connection closed:
the samples FortuneServer and FortuneClient do not use incomingConnection directly either, they are very lean examples. The examples to not call addPendingConnection either.
The important difference here is that the FortuneServer example does not subclass QTcpServer or QTcpSocket. When you subclass it and reimplement functions, there are more gotchas to watch out for.
Your program looks quite complex; I suggest you start by implementing a simple "lean" program from scratch first (without subclassing) and make sure that works. After that, you can gradually add the extra features that you want.
-
@KroMignon , How can you possibly know what I'm trying to do, of course I want to understand it.
The issue is I have such a lot of work ahead of me that I just don't have the luxury of spending hours on one particular problem.
@SPlatten said in QTcpSocket / QTcpServer, connection closed:
The issue is I have such a lot of work ahead of me that I just don't have the luxury of spending hours on one particular problem.
In french we say "Il ne faut pas confondre vitesse et précipitation!", could be translate with "Speeding up is not the same as rushing. "
We don't have the same perception about "losing time".
I believe that spending 5~10 minutes to understand the Qt "basics" will helps you to save even more time later to not have to undo and redo what you have done and not works properly.But this is up to you, which you good luck for your development.
-
@JKSH The intention is that any complexity is hidden and the end result is much cleaner and easier to use.
@SPlatten said in QTcpSocket / QTcpServer, connection closed:
@JKSH The intention is that any complexity is hidden and the end result is much cleaner and easier to use.
I was referring to the complexity of your implementation. Its complexity made it hard for you to understand where your errors were coming from.
I believe you'll have better success in the future if you start learning a new class by implementing simple and "lean" code from scratch first, make sure it works correctly first, and then gradually add more features on top.
Furthermore, you can hide complexity without subclassing/inheritance. You could hide the QTcpServer as a member variable of another class instead. We should often prefer composition over inhertance -- If you took this approach, you wouldn't have needed
addPendingConnection()
and you would've avoided the issues you raised in this thread.I have such a lot of work ahead of me that I just don't have the luxury of spending hours on one particular problem.
Please understand: @KroMignon's concerns are not specific to this particular problem. He's asking you to develop an understanding of some foundational concepts of C++ and QObjects which apply to most of your code -- not just TCP-related code.
Do you understand now? In this line
clsSocketClient* pClient = new clsSocketClient(new QTcpSocket());
:- What does
new clsSocketClient()
do? - What does
new QTcpSocket()
do? - What happens when you pass
new TcpSocket()
into the constructor of yourclsSocketClient
? - What happens when you pass
nullptr
into the constructor of yourclsSocketClient
?
- What does