IS QTSocket a bogus?
-
Hi ,
I send two packets to QTSocket .My ReadyRead is unblocked only once .very pathethic this made to leave the QTSocketing and go for windows sockets .please help.
1.Why ReadyReady is not unblocked twice .
2.same ip and port when new connection is called for the first packet .and ready read also called .i try not to process the message as it may cause the slot not called for second packet . just print alone readReady() functgion called .
I get only one debug print for the first message and for the second message my readyReady never unblocked . -
@mariappan said in IS QTSocket a bogus?:
1.Why ReadyReady is not unblocked twice .
2.same ip and port when new connection is called for the first packet .and ready read also called .i try not to process the message as it may cause the slot not called for second packet .Because that is how a stream is working - there are no 'packets' on the wire, just bytes in a stream without any additional information. This will also be the same if you use pure WinAPI or anything else.
-
@Christian-Ehrlicher thanks for the quick reply .
As i understand normal window socket- accept is blocking call when a new connection comes it gets unblocked.
- recev is also a blocking call when ever the client sends data it gets unblocked and since recev is while(1) loop in server ,server once again waits on blocked Recev call for the another packet .
Coming to QTSocket
connect for new connection is unblocked . when client connects to the server for the first time and goes to execute the connect of ReadyRead.
now client send the data .
ReadyReady needs to be unblocked .
after few second
now client send another data
ReadyReady should be unblocked second time .I am stuck up here .please help
-
@mariappan said in IS QTSocket a bogus?:
ReadyReady needs to be unblocked .
What does this mean? readyRead() signal is emitted as soon as there is data available (except you are blocking the event loop to prevent the signal emission).
-
@Christian-Ehrlicher hi Christian.
Basically this my intension
struct Data1{
int a,
int b,
int d,
};
struct Data2{
int x;
int y ;
int z;
};Serilized data1(12bytes suppose) using memcpy used sent through QTCP Client socket .
after some second delay
Serilized data2((12bytes suppose) using memcpy and sent through QTCP client socket .Server side .
pseduo code
connect(QTCPServer ....... slot(newconnection()));my newconnection function is called .
void newconnection()
{
connect(QTCPSocket,signal(ReadyRead(),,,,,slot(ReadData());
}void ReadData()
{
cout<<"Read data claalled"
QByteStream data = QTCPSocket->ReadAll();
cout<<data.size() // it prints 12 . if altleast printed 24 i would rather agree it is bytestream it send at one shot and i need to work on segregating the message manually. but the size is only 12 bytes .with wireshark data is sent and received confirmation is done.
tried to invoke event loop but still i didnt get the second packet.
please help...
-
It does work for all others so you are doing something wrong. So either work through the examples of QTcpSocket (Fortune server/client, leave alone the threading examples, they are not neeeded in your case) or provide a minimal, compilable example to reproduce your issue (and please format you code with the code - tags (
</>
button) so it is readable. -
@mariappan
The Qt socket stuff works fine and as documented. If the firstreadyRead()
only gets 12 bytes, for whatever reason, the signal will be emitted again for the further 12 bytes. Make sure (a) you have the event loop running and (b) you exit your slot when you are done with the first 12 bytes. https://doc.qt.io/qt-6/qiodevice.html#readyReadThis signal is emitted once every time new data is available for reading from the device's current read channel. It will only be emitted again once new data is available, such as when a new payload of network data has arrived on your network socket, or when a new block of data has been appended to your device.
readyRead() is not emitted recursively; if you reenter the event loop or call waitForReadyRead() inside a slot connected to the readyRead() signal, the signal will not be reemitted
If you want to verify remove all your code and just try a standalone minimal program.
-
@JonB thanks JonB .
Things goes back to 2014 .
https://forum.qt.io/topic/48868/solved-qtcpsocket-readyread-only-signaled-once/4?_=1712905617681But normally TCP_RESET will be called for all messages . i dont know how he solved .
And also i made sure i dont sit in slot function i just print the size and come out immeditately
-
@mariappan
But the link you quote ended with the OP saying:Fixed, turned out to be an issue with the server. The server was not replying to messages until a TCP reset occurred, then it would start replying to messages again, but at that time readyRead would not fire. Fixing the server seemed to have fixed to readyRead issue.
So it was apparently not even a Qt bug then.
Honestly, if you wan t to report a problem here you will need to show a minimal piece of code illustrating it. Remember that loads of people are using
QTcpSocket
.... -
@JonB Thanks JonB
I made sure .
- i didnt start a thread for the eventloop to exists
- i didnt use waitforreadyReady() inside a loop .
wanted only two prints "Called ReadData" slots for two messages .
- create QObjectclass and created tcpclient , tcpserver, tcpsocket .
2.sent the serlized data one after another .
There is no event loop as i am not in threads .
This made go back to winsocket . i dont know anything i am missing
-
@mariappan said in IS QTSocket a bogus?:
This made go back to winsocket . i dont know anything i am missing
Do whatever you want - as we already told you it works but you doing something wrong and there are even full working examples in the link I gave you but you ignore them.
Stripping down an app to reproduce the issue to a minimal, compilable example is the basic work of an developer. -
@mariappan said in IS QTSocket a bogus?:
i dont know anything i am missing
When you want to report a bug or problem in a piece of software you need to supply a minimal reproducible example. This is standard across all software. Then either people might show what you have done "wrong" or agree there is indeed a problem, in which case it will be investigated.
-
@mariappan Perhaps if you run this client/server pair you will better understand what is happening, and why this is not "a bogus".
Client:
#ifndef CLIENT_H #define CLIENT_H #include <QObject> #include <QTcpSocket> #include <QTimer> class Client : public QObject { Q_OBJECT public: explicit Client(QObject *parent = nullptr); private slots: void handleConnected(); void handleDisconnected(); void handleErrorOccurred(QAbstractSocket::SocketError socketError); void handleBytesWritten(qint64 bytes); void sendPacket(); private: QTcpSocket *m_socket; QTimer *m_timer; int m_packetNo; }; #endif // CLIENT_H
#include "client.h" #include <QTimer> #include <QRandomGenerator> Client::Client(QObject *parent) : QObject{parent} , m_socket{ new QTcpSocket(this) } , m_timer{ new QTimer(this) } , m_packetNo{0} { m_timer->setInterval(500); connect(m_timer, &QTimer::timeout, this, &Client::sendPacket); connect(m_socket, &QTcpSocket::connected, this, &Client::handleConnected); connect(m_socket, &QTcpSocket::disconnected, this, &Client::handleDisconnected); connect(m_socket, &QTcpSocket::errorOccurred, this, &Client::handleErrorOccurred); connect(m_socket, &QIODevice::bytesWritten, this, &Client::handleBytesWritten); m_socket->connectToHost(QHostAddress("127.0.0.1"), 12345); } void Client::handleConnected() { qDebug() << "Connected, sending packets."; m_timer->start(); } void Client::handleDisconnected() { qDebug() << "Disconnected"; m_timer->stop(); } void Client::handleErrorOccurred(QAbstractSocket::SocketError socketError) { qDebug() << "Error occured" << socketError; m_timer->stop(); } void Client::handleBytesWritten(qint64 bytes) { qDebug() << "Bytes written" << bytes; } void Client::sendPacket() { // Generate a sample fixed-length payload QByteArray data; data.setNum(m_packetNo++); data = data.rightJustified(32, '.'); m_socket->write(data); qDebug() << "Wrote" << data; // Sometimes we write more than one quint32 value = QRandomGenerator::global()->generate(); if ((value % 3) == 1) { data.setNum(m_packetNo++); data = data.rightJustified(32, '*'); m_socket->write(data); qDebug() << "Wrote" << data; } }
#include <QCoreApplication> #include <QDebug> #include <QTimer> #include "client.h" int main(int argc, char **argv) { QCoreApplication app(argc, argv); Client client; QTimer::singleShot(30000, qApp, &QCoreApplication::quit); return app.exec(); }
Server:
#ifndef SERVER_H #define SERVER_H #include <QObject> #include <QTcpServer> class Server : public QObject { Q_OBJECT public: explicit Server(QObject *parent = nullptr); private slots: void handleNewConnection(); private: QTcpServer *m_server; }; class ClientHandler: public QObject { Q_OBJECT public: explicit ClientHandler(QTcpSocket *socket, QObject *p = nullptr); private slots: void handleReadyRead(); void handleDisconnected(); private: QTcpSocket *m_socket; }; #endif // SERVER_H
#include "server.h" #include <QDebug> #include <QTcpSocket> Server::Server(QObject *parent) : QObject{parent} , m_server{ new QTcpServer(this) } { connect(m_server, &QTcpServer::newConnection, this, &Server::handleNewConnection); m_server->listen(QHostAddress("127.0.0.1"), 12345); } void Server::handleNewConnection() { while(m_server->hasPendingConnections()) { QTcpSocket *socket = m_server->nextPendingConnection(); qDebug() << "Accepted connection from " << socket->peerAddress() << socket; ClientHandler *client = new ClientHandler(socket, this); Q_UNUSED(client); } } ClientHandler::ClientHandler(QTcpSocket *socket, QObject *p) : QObject(p) , m_socket(socket) { socket->setParent(this); connect(socket, &QTcpSocket::readyRead, this, &ClientHandler::handleReadyRead); connect(socket, &QTcpSocket::disconnected, this, &ClientHandler::handleDisconnected); } void ClientHandler::handleReadyRead() { qDebug() << m_socket<< "readyRead received."; QByteArray data = m_socket->readAll(); qDebug() << data; } void ClientHandler::handleDisconnected() { qDebug() << m_socket << "disconnect"; deleteLater(); }
#include <QCoreApplication> #include "server.h" int main(int argc, char **argv) { QCoreApplication app(argc, argv); Server server; return app.exec(); }
-