I use qt4.8.5 and windows.
I use QTcpSocket to connect a server.
If the server doesn't open, then I will try to connect it.
My way is:
sock = new QTcpSocket(this);
sock->connectToHost("127.0.0.1", 1234);
connect(sock, SIGNAL(disconnected()), this, SLOT(disconnected()));
connect(sock, SIGNAL(error(QAbstractSocket::SocketError)),
this, SLOT(error(QAbstractSocket::SocketError)));
I will get the error() signal.
sock->close();
sock->deletelater();
I use a timer to try to connect, and it did call the error() to delete the sock.
But I found that the handles increase in the Task Manager. Does it have memory leak? but I have close the sock and use deletelater().
What's more, the socket object not run in the main thread.
If any one know the reason cause the handles increase, please tell me.
Thanks!
Related
I am using Qt for unix domain socket and I have a question:
I want the server side read the message sent from the client side right after the connection established, below are my codes
if (!server->listen("mySocket2")) {
//lisetn for new connection
close();
return;
}
connect(server, &QLocalServer::newConnection, this, &MainWindow::readData);
And in the readData function
QLocalSocket *clientConnection = server->nextPendingConnection();
connect(clientConnection, &QLocalSocket::disconnected,
clientConnection, &QLocalSocket::deleteLater);
connect(clientConnection,&QLocalSocket::readyRead,
this,&MainWindow::readyReadData);
In the readyReadData function
QByteArray block;
block=clientConnection->readAll();
qDebug()<<block;
clientConnection->disconnectFromServer();
but the app always crashed, can you plz advise me on that?
I don't see any condition handling for when there are no pending connections. This case will cause nextPendingConnection() to return a nullptr (actually, just a zero), which may or may not cause the signal/slot connections to fail.
My question title should be enough. I already tried (without success):
Using a C-style destructor in a function: __attribute__((destructor)):
void sendToServerAtExit() __attribute__((destructor)) {
mySocket->write("$%BYE_CODE%$");
}
The application destructor is called, but the socket is already disconnected and I can't write to the server.
Using the standard C function atexit(), but the TCP connection is already lost so I can't send anything to the server.
atexit(sendToServerAtExit); // is the same function of point 1
The solution I found is check every second if all connected sockets are still connected, but I don't want to do so inefficient thing. It's only a temporary solution. Also, I want that others apps (even web ones) can join the chat room of my console app, and I don't want to request data every second.
What should I do?
Handle the below signal (QTcpSocket is inherited from QAbstractSocket)
void QAbstractSocket::stateChanged(QAbstractSocket::SocketState socketState)
Inside the slot called, check if socketState is QAbstractSocket::ClosingState.
QAbstractSocket::ClosingState indicates the socket is about to close.
http://doc.qt.io/qt-5/qabstractsocket.html#SocketState-enum
You can connect a slot to the disconnect signal.
connect(m_socket, &QTcpSocket::disconnected, this, &Class::clientDisconnected);
Check the documentation.
You can also know which user has been disconnected using a slot like this:
void Class::clientDisconnected
{
QTcpSocket* client = qobject_cast<QTcpSocket*>(sender());
if(client)
{
// Do something
client->deleteLater();
}
else
{
// Handle error
}
}
This method is usefull if you have a connections pool. You can use it as well if you have a single connection, but do not forget nullptr after client->deleteLater().
If I understand you question correctly, you want to send data over TCP to notify the remote computer that you are closing the socket.
Technically this can be done in Qt by listenning to the QIODevice::aboutToClose() or QAbstractSocket::stateChanged() signals.
However, if you graciously exit your program and close the QTcpSocket by sending a FIN packet to the remote computer. This means that on the remote computer,
the running program will be notified that the TCP connection finished. For instance, if the remote program is also using QTcpSocket, the QAbstractSocket::disconnected()
signal will be emitted.
The real issues arise when one of the program does not graciously exit (crash, hardware issue, cable unplugged, etc.). In this case, the TCP FIN packet will
not be sent and the remote computer will never get notified that the other side of the TCP connection is disconnected. The TCP connection will just time-out after a few minutes.
However, in this case you cannot send your final piece of data to the server either.
In the end the only solution is to send a "I am here" packet every now and then. Even though you claim it is ineficient, it is a widely used technique and it also has the advantage that it works.
When dealing with QNetworkReply, it is prescribed to use timers to abort the connection.
Here is my current code:
void ImageDownloader::download(QString imgUrl){
this->timeoutTimer = new QTimer(this);
this->timeoutTimer->setSingleShot(true);
this->timeoutTimer->setInterval(15000);
connect(this->timeoutTimer, SIGNAL(timeout()), this, SLOT(timeout()));
QUrl requestUrl(imgUrl);
QNetworkRequest nwRequest(requestUrl);
this->imageNwReply = this->nam->get(nwRequest);
connect(imageNwReply,SIGNAL(finished()),this,SLOT(imgDownloaded()));
connect(imageNwReply, SIGNAL(downloadProgress(qint64,qint64)), this->timeoutTimer, SLOT(start()));
this->timeoutTimer->start();
}
void ImageDownloader::timeout(){
qDebug()<<__FUNCTION__<<" Forced timeout!";
this->imageNwReply->abort();
}
The confusion I am facing is when should I start the timer? At times I have to make around 50 concurrent Get requests from QNetworkAccessManager but since there is throttling for maximum concurrent connections, at times it happens that some of the requests get timed out even before they have been processed.
Is there a signal to know exactly when the processing for a request is started by QNeworkAccessManager so that I can start the corresponding timer only then?
One possible solution might be to implement a Queue of requests and have only the maximum possible connections to process but I am looking for a cleaner solution
There is an open bug/enhancement request for the issue. I got to know about this bug from Qt forum
I have written a multithreaded application in C. I have two threads created, one for catching all the signals and another for accept()-ing client connections. When I kill the appilcation using killproc, the thread with the accept call is not interrupted. How can I fix that?
The code looks like:
int stop_exec=0;
sigCatcherThread()
{
int sig
sigset_t allsignals;
sigfillset(allsignals);
do{
sigwait(&allsignals, &sig);
if(sig==SIGTERM)
stop_exec=1;
}while(!stop_exec)
}
clientHandler()
{
...
while(!stop_exec)
{
accept(...);
}
main()
{
pthread_create(..., sigCatcherThread,..);
pthread_create(..., clientHandler,...);
}
Here you see the use of interrupted system calls. But the convenience of a signal handling thread is probably higher than the use of interrupted systems calls.
So you need you client handler to block until it can accept an incoming connection or the signal occurs. Waiting for potential input means either signal driven IO -- a path I wouldn't follow -- or select(2) (or pool). But select(2) can wait only on IO. So transform your signal occurrence in IO: open a pipe, have your signal handling thread write to the pipe when SIGQUIT occurs and have your client thread select(2) for the socket and the other end of the pipe.
Only one thread receives a signal targeted to a process. So, it must be not the thread blocked on accept(). See signal concepts for more details.
As already mentioned here, you should probably be using an event loop based on select(). I would suggest using libevent.
There's no need to interrupt the blocking accept call. Just make sure that if the thread does return from accept, say by receiving an actual connection, it won't do anything harmful.
If there's some specific reason you need the accept call to interrupt, explain what it is. Likely there's a simple way to remove the requirement.
I'm new to Qt, but I have some experience in C and Java.
I'm trying to write a program that makes multiple TCP connections to different servers on the network.
the ip's are read in from a text file and i use connectToHost to establish a connection then the socket is added to a QList. this happens in a loop.
the problem is that i only start receiving the connected() signals when the program exits the loop, this causes some unexpected behaviour.
so is there a way to poll for signals in the loop?
call QCoreApplication::processEvents() inside your loop to avoid freezing
You can use QAbstractSocket::waitForConnected()
http://doc.qt.io/qt-5/qabstractsocket.html#waitForConnected