QTcpServer newConnection slot not being called
-
I am trying to write a plugin for Wireshark, a Qt GUI application. Wireshark is mostly written in C with C++ and Qt used to handle the user interface. The plugin framework comprises mainly a set of three or four C callback functions. I'm writing the plugin in C++, exposing the callbacks using extern "C" declarations. The callbacks are being called correctly and that all looks fine.
The plugin needs to provide a TCP server. I've cribbed various servers from examples on the web, and they work except for in one respect; the slots in my plugin classes never get called.
The code looks like this:
mytcpserver.h
#ifndef MYTCPSERVER_H #define MYTCPSERVER_H #include <QObject> #include <QTcpSocket> #include <QTcpServer> #include <QDebug> class MyTcpServer : public QObject { Q_OBJECT public: explicit MyTcpServer(QObject *parent = 0); signals: public slots : void newConnection(); private: QTcpServer *server; }; #endif // MYTCPSERVER_H
mytcpserver.cpp
// mytcpserver.cpp #include "mytcpserver.h" MyTcpServer::MyTcpServer(QObject *parent) : QObject(parent) { server = new QTcpServer(this); // whenever a user connects, it will emit signal connect(server, SIGNAL(newConnection()), this, SLOT(newConnection())); if (!server->listen(QHostAddress::Any, 8888)) { qDebug() << "Server could not start"; } else { qDebug() << "Server started!"; } } void MyTcpServer::newConnection() { // need to grab the socket QTcpSocket *socket = server->nextPendingConnection(); socket->write("Hello client\r\n"); socket->flush(); socket->waitForBytesWritten(3000); socket->close(); }
packet-syncro.cpp These are excerpts from the file with the callbacks
static MyTcpServer *myServer; void proto_register_syncro(void) { module_t *syncro_module; proto_syncro = proto_register_protocol("Syncro Service", "Syncro", "syncro"); syncro_module = prefs_register_protocol(proto_syncro, proto_reg_handoff_syncro); if (!myServer) { myServer = new MyTcpServer; } return; }
proto_register_syncro is one of the callback functions that get called two or three times during Wireshark startup.
This all creates a DLL called syncro.dll, which builds, loads and runs without problem. I then start Wireshark and use Putty to connect to the TCP server. It connects OK but I don't get the "Hello client" message. I also find that the newConnection slot is not called.
All of the above code runs on the main application thread which is own the QMainWindow object.
How does my newConnection slot get added to the Event Loop? What have I done wrong here?
Thanks and regards...Paul
-
If you have no event loop then you must use the blocking call
QTcpServer::waitForNewConnection()
after callingQTcpServer::listen()
.You may need to have a separate thread to run a Qt event loop in or to make calls to the blocking
wait...()
member functions. If you have no other need for Qt then the thread withwait...()
blocking calls is probably easiest. Either way you need to synchronize communications between the thread and rest of wireshark. -
If you have no event loop then you must use the blocking call
QTcpServer::waitForNewConnection()
after callingQTcpServer::listen()
.You may need to have a separate thread to run a Qt event loop in or to make calls to the blocking
wait...()
member functions. If you have no other need for Qt then the thread withwait...()
blocking calls is probably easiest. Either way you need to synchronize communications between the thread and rest of wireshark.@bsomervi Thanks for your response.
I have tried four different variations of solution, including the one you suggest. The code I am writing needs to be able to call a function in the context of the main thread. When I built a solution with a separate thread to run the TCP server, this worked fine but I still needed to be able to run a function under the main thread, which I attempted with a cross-thread signal and slot. I had the same problem; the slot didn't get called if I specified a connect with a QueuedConnection type. If I specified DirectConnection, the slot was called but of course it was called in the context of the thread running my TCP server and not the main thread.
Whatever way I choose, I need to get a slot function to run in the context of the main thread which I understand means it must be serviced by an Event Loop in the main thread.
-
Hi and welcome to devnet,
Out of curiosity, why do you need your callback to be run in the main thread ?
-
Hi and welcome to devnet,
Out of curiosity, why do you need your callback to be run in the main thread ?
@SGaist Thanks. There are two reasons for needing to run the code on the main thread.
Wireshark displays network packet data. My plugin calls a plugin interface function to cause Wireshark to jump from the currently displayed packet to another (the parameter passed is the new packet number). Somewhere deeper into the code the plugin interface emits signals to update various aspects of the Wireshark window. If I call the plugin interface on my own thread, the slots for these signals don't get called. If I call them from the main thread they do.
The second reason is that there are circumstances where an error might occur e.g. using the plugin interface to jump to a packet that is not actually being displayed (Wireshark has display filtering that might cause this). In this case Wireshark tries to output an error message via a QtWidget but because I'm not running on the main thread this causes an exception. I can't remember the precise wording of the exception but it's something like "you can't output to a QtWidget when you are not running on the main thread".
-
How are you setting up your threaded code ?
-
@SGaist I've continued this discussion on https://forum.qt.io/topic/61743/slot-on-main-thread-not-called-when-signal-is-emitted-from-another-thread as the issue with the multithreaded version is slightly different and doesn't match the Topic Title.
-
I pursued this in a slightly different way as described in https://forum.qt.io/topic/61743/slot-on-main-thread-not-called-when-signal-is-emitted-from-another-thread. However, I'm pretty sure the fix was the same. I had been mixing release and debug versions of objects and this seems to upset the signal/slot mechanism. See the above link for more information.