How do I know that the client has connected to the server?
-
@NintyS said in How do I know that the client has connected to the server?:
but void in connect don't start.
What does this mean? I don't understand.
-
In Connect I use signal to active void newConnection. ( Or maybe I don't understand something )
#include "server.hpp" server::server(QObject *parent) : QObject(parent) { serverObject = new QTcpServer(this); connect(serverObject, SIGNAL(newConnection()), this, SLOT(newConnection())); if(serverObject->listen(QHostAddress::Any, 50153)) { printf("Yes"); } else { printf("No"); } } void server::newConnection() { printf("123"); QTcpSocket *socket = serverObject->nextPendingConnection(); socket->write("Test\n"); socket->flush(); socket->waitForBytesWritten(300); socket->close(); }
( I understand this that: if ( connect ) something ( signal ) then something ( slot )
-
And with which program do you connect to this port? Are you sure it really connects to your address?
And please use the new signal/slot syntax. -
@NintyS said in How do I know that the client has connected to the server?:
No, I'm not sure but when I close the program then I have a message "connected", so I thinking I connect with my server.
Sorry but please be more precise. Why do you get a 'connected' when you close a program? This doesn't sounds very useful. What program is this? Please use a simple QTcpSocket as shown in the QTcpServer examples to check your program. Or try to connect with e.g. telnet to your listen port.
-
This is working fine for me:
#include <QtNetwork> int main(int argc, char* argv[]) { QCoreApplication app(argc, argv); QTcpServer server; if (!server.listen(QHostAddress::Any, 50153)) return 1; QObject::connect(&server, &QTcpServer::newConnection, &server, [&server]() { QTcpSocket *socket = server.nextPendingConnection(); qDebug() << "client connected from" << socket->peerAddress() << ":" << socket->peerPort(); socket->write("Test\n"); socket->flush(); socket->waitForBytesWritten(300); socket->close(); }); QTcpSocket client; QObject::connect(&client, &QTcpSocket::readyRead, &client, [&client]() { qDebug() << client.readAll(); QCoreApplication::quit(); }); client.connectToHost("localhost", 50153); return app.exec(); }
-
@Christian-Ehrlicher said in How do I know that the client has connected to the server?:
socket->flush(); socket->waitForBytesWritten(300);
Does one have to have these two lines prior to
socket->close()
, or are you just being "safe"? -
The waitForBytesWritten() is needed.
-
@Christian-Ehrlicher I know now why. I use a printf() to show the result. Now when I use qDebug I see my result after connection.
-
@NintyS
printf()
is liable to be at least line-buffered, maybe even fully buffered. You would have to follow it withfflush(stdout)
to try to see the output immediately.fprintf(stderr, ...)
would probably be better. In any caseqDebug()
is a better choice for debugging. -
@Christian-Ehrlicher said in How do I know that the client has connected to the server?:
the waitForBytesWritten() is needed.
Why? My understanding was that
waitForBytesWritten()
is only required if not event queue is available... But without event queue, theconnect()
won't work. -
@KroMignon Because of the close() directly afterwards. I'm pretty sure close() will call flush() before but it's not documented.
-
@KroMignon probably because of the immediate call to close on the socket
you could alternatively, potentially nest lambdas
QTcpSocket *socket = server.nextPendingConnection(); qDebug() << "client connected from" << socket->peerAddress() << ":" << socket->peerPort(); QByteArray data{"Test\n"}; QObject::connect(socket, &QTcpSocket::bytesWritten, socket, [socket, bytesToSend = data.size()](qint64 bytes)->void{ static qint64 bytesSend{0}; bytesSend += bytes; if(static_cast<qint64>(bytesToSend) == bytesSend) socket->close(); }); socket->write(data); });
-
@J-Hilk said in How do I know that the client has connected to the server?:
you could alternatively, potentially nest lambdas
QTcpSocket *socket = server.nextPendingConnection(); qDebug() << "client connected from" << socket->peerAddress() << ":" << socket->peerPort(); QByteArray data{"Test\n"}; QObject::connect(socket, &QTcpSocket::bytesWritten, socket, [socket, bytesToSend = data.size()](qint64 bytes)->void{ static qint64 bytesSend{0}; bytesSend += bytes; if(static_cast<qint64>(bytesToSend) == bytesSend) socket->close(); }); socket->write(data); });
Hmm, I would do it like this:
QTcpSocket *socket = server.nextPendingConnection(); qDebug() << "client connected from" << socket->peerAddress() << ":" << socket->peerPort(); QByteArray data{"Test\n"}; QObject::connect(socket, &QTcpSocket::bytesWritten, socket, [socket](qint64 bytes)->void{ if(socket->bytesToWrite() == 0) socket->close(); }); socket->write(data);
-
@KroMignon potentially, I'm not familiar enough with the inner workings of QAbstractSocket to say for sure, that bytesToWrite is updated before bytesWritten is emitted 🤷♂️
-
@J-Hilk said in How do I know that the client has connected to the server?:
static qint64 bytesSend{0};
You might like to come join us in my question about this over at https://forum.qt.io/topic/123582/static-in-lambda ? :)