QUdpSocket readyRead() is not emitted
-
Re: QUdpSocket readyRead never emitted
I believe I'm seeing the same issue where my readyRead() signal from QUdpSocket is not being emitted.
This thread last updated a year ago does not seem to have the solution:
https://forum.qt.io/topic/85860/qudpsocket-readyread-never-emitted/15I'm very puzzled and am currently using a while loop with a 20ms wait but of course this is not an ideal workaround. We want to take advantage of the event loop triggering the readyRead() signal. I did try the bytesAvailable() signal as suggested above without any luck.
Here is my code in case anyone can provide advice. It would be greatly appreciated. I am developing on Ubuntu 18.04 with Qt5.9.5 and another person on stackoverflow has indicated that it is working for him on his mac os.
myudp.hclass MyUDP : public QObject { Q_OBJECT public: explicit MyUDP(QObject *parent); void initSocket(u_int16_t p); private: u_int16_t port; QUdpSocket *udpSocket = nullptr; signals: private slots: void processPendingDatagrams(); void onSocketStateChange (QAbstractSocket::SocketState state); void testSlot(); };myudp.cpp
#include "myudp.h" MyUDP::MyUDP(QObject *parent) : QObject(parent) { } void MyUDP::testSlot() { qDebug() << "test slot..." << endl; } void MyUDP::initSocket(u_int16_t p) { port = p; udpSocket = new QUdpSocket(this); bool bindSuccess = udpSocket->bind(QHostAddress::AnyIPv4, port); if (!bindSuccess) { qDebug() << "Error binding to port " << port << " on local IPs"; return; } qDebug() << "Bound to port " << port << " on local IPs"; processPendingDatagrams(); connect(udpSocket, SIGNAL(readyRead()), this, SLOT(processPendingDatagrams()), Qt::QueuedConnection); connect(udpSocket, SIGNAL(readyRead()), this, SLOT(testSlot()), Qt::QueuedConnection); } void MyUDP::processPendingDatagrams() { qDebug() << "readPendingDatagrams()\n"; QHostAddress sender; while (udpSocket->hasPendingDatagrams()) { QByteArray datagram; datagram.resize(udpSocket->pendingDatagramSize()); udpSocket->readDatagram(datagram.data(), datagram.size(), &sender, &port); qDebug() << "Message From :: " << sender.toString(); qDebug() << "Port From :: " << port; qDebug() << "Message :: " << datagram.data(); } }main.cpp
int main(int argc, char *argv[]) { u_int16_t port = 7777; qDebug() << "MyUDP version. " << endl; MyUDP *myUDP = new MyUDP(0); myUDP->initSocket(port); QCoreApplication a(argc, argv); a.exec(); return 0; } -
Can u see example[link text](link https://forum.qt.io/topic/98601/qudpsocket-simple-communication-between-2-qt-applications)here and try
-
I found my issue. Need to do the connect call and binding after the QCoreApplication a(...) is declared and then follow with the a.exec(). Apparently I was doing it after and it makes a difference.
int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); u_int16_t port = 7777; MyUDP *myUDP = new MyUDP(0); myUDP->initSocket(port); return a.exec(); } -
This was the precise issue and hence requested you to look at previous post.
-
Thank you! I just happen to stumble by dumb luck across the answer as you were posting. Appreciate your time.
-
Hi Dheerendra,
If you have a moment for a follow up question. We have a non qmake build and I'm noticing that we get this error when I try to compile with the Q_OBJECT macro.
obj/udp_server.o: In function `udp_server::udp_server(QObject*)': udp_server.cpp:(.text+0xc): undefined reference to `vtable for udp_server'Can I substitute come command line build commands and have the Q_OBJECT macro removed? Can you advise on how to inherit a class from qobject to use signal slots without needing to port our make file to a qmake pro format?
Am I just calling moc <myfile.h>; moc <myfile.cpp> and then compiling with the two newly generated files from moc? Or is there more to it than that?
-
Hi Dheerendra,
If you have a moment for a follow up question. We have a non qmake build and I'm noticing that we get this error when I try to compile with the Q_OBJECT macro.
obj/udp_server.o: In function `udp_server::udp_server(QObject*)': udp_server.cpp:(.text+0xc): undefined reference to `vtable for udp_server'Can I substitute come command line build commands and have the Q_OBJECT macro removed? Can you advise on how to inherit a class from qobject to use signal slots without needing to port our make file to a qmake pro format?
Am I just calling moc <myfile.h>; moc <myfile.cpp> and then compiling with the two newly generated files from moc? Or is there more to it than that?
@James-Mark-Chan Do you also compile and link generated moc_*.cpp files?
You can do an#include <moc_myfile.cpp>at the end of you myfile.cpp
-
Hi, a quick update. After I added these lines
https://stackoverflow.com/questions/54263057/processing-of-q-object-in-legacy-non-qmake-build/
I was able to build on my system locally but when I try and build on the remote build server I am getting these errors:18-Jan-2019 17:42:57 In file included from udp_server.cpp:2:0: 18-Jan-2019 17:42:57 db.h:45:2: error: ‘uint32_t’ does not name a type 18-Jan-2019 17:42:57 uint32_t cont_type; 18-Jan-2019 17:42:57 ^ 18-Jan-2019 17:42:57 db.h:46:2: error: ‘uint32_t’ does not name a type 18-Jan-2019 17:42:57 uint32_t valve; 18-Jan-2019 17:42:57 ^ 18-Jan-2019 17:42:57 db.h:47:2: error: ‘uint32_t’ does not name a type 18-Jan-2019 17:42:57 uint32_t head; 18-Jan-2019 17:42:57 ^ 18-Jan-2019 17:42:57 db.h:48:2: error: ‘uint32_t’ does not name a type 18-Jan-2019 17:42:57 uint32_t fill_level; 18-Jan-2019 17:42:57 ^ 18-Jan-2019 17:42:57 udp_server.cpp: In member function ‘void udp_server::processPendingDatagrams()’: 18-Jan-2019 17:42:57 udp_server.cpp:53:15: error: ‘struct fms_data_t’ has no member named ‘cont_type’ 18-Jan-2019 17:42:57 fms.cont_type = jmap["cont_type"].toInt(); 18-Jan-2019 17:42:57 ^ 18-Jan-2019 17:42:57 udp_server.cpp:54:15: error: ‘struct fms_data_t’ has no member named ‘valve’ 18-Jan-2019 17:42:57 fms.valve = jmap["valve"].toInt(); 18-Jan-2019 17:42:57 ^ 18-Jan-2019 17:42:57 udp_server.cpp:55:15: error: ‘struct fms_data_t’ has no member named ‘head’ 18-Jan-2019 17:42:57 fms.head = jmap["head"].toInt(); 18-Jan-2019 17:42:57 ^ 18-Jan-2019 17:42:57 udp_server.cpp:56:15: error: ‘struct fms_data_t’ has no member named ‘fill_level’ 18-Jan-2019 17:42:57 fms.fill_level = jmap["fill_level"].toInt(); 18-Jan-2019 17:42:57 ^I was wondering what the issue could be. I'm a far more experienced java developer so am not that familiar with qt troubleshooting. The remote system is Ubuntu 16.04 with:
QMake version 3.0 Using Qt version 5.5.1 in /usr/lib/x86_64-linux-gnuAnd my local development environment is ubuntu 18.04
QMake version 3.1 Using Qt version 5.9.5 in /usr/lib/x86_64-linux-gnuIs this because of the version mismatch? I'm not actually using qmake so the version of make on both the build server and my local workstation is:
GNU Make 4.1 Built for x86_64-pc-linux-gnuAny advice is really appreciated!!!
-
Hi, a quick update. After I added these lines
https://stackoverflow.com/questions/54263057/processing-of-q-object-in-legacy-non-qmake-build/
I was able to build on my system locally but when I try and build on the remote build server I am getting these errors:18-Jan-2019 17:42:57 In file included from udp_server.cpp:2:0: 18-Jan-2019 17:42:57 db.h:45:2: error: ‘uint32_t’ does not name a type 18-Jan-2019 17:42:57 uint32_t cont_type; 18-Jan-2019 17:42:57 ^ 18-Jan-2019 17:42:57 db.h:46:2: error: ‘uint32_t’ does not name a type 18-Jan-2019 17:42:57 uint32_t valve; 18-Jan-2019 17:42:57 ^ 18-Jan-2019 17:42:57 db.h:47:2: error: ‘uint32_t’ does not name a type 18-Jan-2019 17:42:57 uint32_t head; 18-Jan-2019 17:42:57 ^ 18-Jan-2019 17:42:57 db.h:48:2: error: ‘uint32_t’ does not name a type 18-Jan-2019 17:42:57 uint32_t fill_level; 18-Jan-2019 17:42:57 ^ 18-Jan-2019 17:42:57 udp_server.cpp: In member function ‘void udp_server::processPendingDatagrams()’: 18-Jan-2019 17:42:57 udp_server.cpp:53:15: error: ‘struct fms_data_t’ has no member named ‘cont_type’ 18-Jan-2019 17:42:57 fms.cont_type = jmap["cont_type"].toInt(); 18-Jan-2019 17:42:57 ^ 18-Jan-2019 17:42:57 udp_server.cpp:54:15: error: ‘struct fms_data_t’ has no member named ‘valve’ 18-Jan-2019 17:42:57 fms.valve = jmap["valve"].toInt(); 18-Jan-2019 17:42:57 ^ 18-Jan-2019 17:42:57 udp_server.cpp:55:15: error: ‘struct fms_data_t’ has no member named ‘head’ 18-Jan-2019 17:42:57 fms.head = jmap["head"].toInt(); 18-Jan-2019 17:42:57 ^ 18-Jan-2019 17:42:57 udp_server.cpp:56:15: error: ‘struct fms_data_t’ has no member named ‘fill_level’ 18-Jan-2019 17:42:57 fms.fill_level = jmap["fill_level"].toInt(); 18-Jan-2019 17:42:57 ^I was wondering what the issue could be. I'm a far more experienced java developer so am not that familiar with qt troubleshooting. The remote system is Ubuntu 16.04 with:
QMake version 3.0 Using Qt version 5.5.1 in /usr/lib/x86_64-linux-gnuAnd my local development environment is ubuntu 18.04
QMake version 3.1 Using Qt version 5.9.5 in /usr/lib/x86_64-linux-gnuIs this because of the version mismatch? I'm not actually using qmake so the version of make on both the build server and my local workstation is:
GNU Make 4.1 Built for x86_64-pc-linux-gnuAny advice is really appreciated!!!
@James-Mark-Chan
uint32_tis instdint.h. you probably miss an include which on your system is implicitely given. -
@James-Mark-Chan
uint32_tis instdint.h. you probably miss an include which on your system is implicitely given.@aha_1980 @James-Mark-Chan Since C++11 it is <cstdint>
https://en.cppreference.com/w/cpp/types/integer -
@aha_1980 @James-Mark-Chan Since C++11 it is <cstdint>
https://en.cppreference.com/w/cpp/types/integer -
@James-Mark-Chan Do you also compile and link generated moc_*.cpp files?
You can do an#include <moc_myfile.cpp>at the end of you myfile.cpp
@jsulm I'm curious if added:
#include <moc_myfile.cpp>Is the benefit that I don't need to compile an independent moc_myfile.o or would that step still be necessary?
-
It seems that another solution could be to do an install of the 5.9 or 5.12 into the target environment. This environment does not have a desktop, does anyone know if the silent installer feature works now? I was thinking of using:
sudo ./qt-opensource-linux-x64-5.12.0.run --platform minimalWill that work or is the script command also necessary?
-
It seems that another solution could be to do an install of the 5.9 or 5.12 into the target environment. This environment does not have a desktop, does anyone know if the silent installer feature works now? I was thinking of using:
sudo ./qt-opensource-linux-x64-5.12.0.run --platform minimalWill that work or is the script command also necessary?
The correct solution is to fix your code. Your build server already told you, that the code is relying on external includes to compile. Now you want to fix this by changing the external includes?!
This problem can come back anytime. Better fix it now.
-
@aha_1980 Thanks for the encouragement. I got this to build last evening by adding:
#include <stdint.h>to our db.h file. I'm not sure if that was the correct solution or if there was something wrong with the make file. Here is the make file for reference:
MAJOR_VER=1 MINOR_VER=0 PATCH_VER=0 DEB_MAINTAINER= ####### Sets include paths FILTEC_BUILD="no" ####### Enable/Disable DEBUG build with "yes" or "no" DEBUG="no" APP_BASE_NAME=historian BUILD_FILE = build.cpp SRCPP = main.cpp db.cpp syslog.cpp log.cpp common.cpp pid.cpp $(BUILD_FILE) SRCPP += mqtt_sub.cpp ve_util.cpp ve_mqtt.cpp udp_server.cpp moc_udp_server.cpp OBJDIR = ./obj BINDIR = ./bin RELDIR = ../release MAKEOBJDIR := $(shell if [ ! -d $(OBJDIR) ]; then mkdir $(OBJDIR) ; fi ) MAKEBINDIR := $(shell if [ ! -d $(BINDIR) ]; then mkdir $(BINDIR) ; fi ) MAKERELDIR := $(shell if [ ! -d $(RELDIR) ]; then mkdir $(RELDIR) ; fi ) APPNAME = $(BINDIR)/$(APP_BASE_NAME) OBJ = $(SRCPP:%.cpp=$(OBJDIR)/%.o) ifeq ($(FILTEC_BUILD),"yes") QTPATH = /home/filtec/Qt5.2.1/5.2.1/gcc_64 QTINCPATH = $(QTPATH)/include else QTPATH = /usr/include QTINCPATH = $(QTPATH)/x86_64-linux-gnu/qt5 endif ####################################### INCLUDEPATH := -I./ -I$(QTINCPATH) -I$(QTINCPATH)/QtCore -I$(QTINCPATH)/QtNetwork -Ithirdparty/mosquitto/include -Ithirdparty/sqlite3/include CFLAGS = -Wall -Wno-trigraphs -pipe -fno-strict-aliasing -fno-common -fshort-enums CFLAGS += $(INCLUDEPATH) -fPIC CFLAGS += -Wformat-security CFLAGS += -DLINUX CFLAGS += -DMAJOR_VERSION=$(MAJOR_VER) CFLAGS += -DMINOR_VERSION=$(MINOR_VER) CFLAGS += -DPATCH_VERSION=$(PATCH_VER) LDLIBS = -lpthread -lQt5Core -lQt5Network LDLIBS += -lsqlite3 LDLIBS += -lmosquitto ifeq (.version,$(wildcard .version)) BUILD_TMP := $(shell eval expr 0`cat .version` + 1 > .version) else BUILD_TMP := $(shell echo 0 > .version) endif BUILD_NUMBER := $(shell cat .version) BUILD_DEB := $(shell eval expr 0`cat .version` + 1) ifeq ($(DEBUG),"yes") CFLAGS += -O1 CFLAGS += -g -rdynamic -DDEBUG DBG_SUFFIX=-dbg else CFLAGS += -O3 endif CC=g++ NM = $(CROSS)nm STRIP = $(CROSS)strip STRIPFLAGS = --strip-all --remove-section=.note --remove-section=.comment ####################################### # FIL-3131 adding patch number to distinguish it from build number #BASENAME = $(APPNAME)-$(MAJOR_VER).$(MINOR_VER).$(BUILD_NUMBER)$(DBG_SUFFIX) BASENAME = $(APPNAME)-$(MAJOR_VER).$(MINOR_VER).$(PATCH_VER)+$(BUILD_NUMBER)$(DBG_SUFFIX) ####################################### .PHONY: all clean do-it-all depend with-depends without-depends all: do-it-all ifeq (.depends,$(wildcard .depends)) include .depends do-it-all: with-depends else do-it-all: without-depends endif without-depends: depend with-depends depend: $(BUILD_FILE) rm -f .depends set -e; for F in $(SRC); do echo -n $(OBJDIR)/ >> .depends; $(CC) -MM $(CFLAGS) $$F >> .depends; done with-depends: $(OBJ) $(BASENAME) ## Compile $(OBJDIR)/%o : %c $(CC) $(INCLUDES) $(CFLAGS) -c $< -o $@ $(OBJDIR)/%o : %cpp $(CXX) $(INCLUDES) $(CFLAGS) -c $< -o $@ $(OBJ): ./Makefile $(BASENAME): $(OBJ) $(CC) $(CFLAGS) $^ -o $@ $(LDLIBS) ifeq ($(DEBUG),"yes") $(NM) $(BASENAME) | sort > $(BASENAME).map else $(STRIP) $(STRIPFLAGS) $@ endif cp $(BASENAME) $(BINDIR)/$(APP_BASE_NAME) $(BUILD_FILE): ./Makefile .version @echo \#include \"main.h\" > .ver @echo -n "const int BuildVersion = " >> .ver @cat .version >> .ver @echo ";" >> .ver @mv -f .ver $@ # BEWARE the debian/changelog format is very, very picky! # There must always be specific numbers of spaces in certain places. # Change with extreme caution. DEB_CHANGELOG=./debian/changelog changelog: ./Makefile $(DEB_CHANGELOG) @echo "$(APP_BASE_NAME) ($(MAJOR_VER).$(MINOR_VER).$(PATCH_VER)-dev+$(BUILD_DEB)) stable; urgency=low\n" > debian/changelog @echo " * Initial Historian Release. See FIL-3131\n" >> debian/changelog @echo -n " -- maintainer $(DEB_MAINTAINER) " >> debian/changelog @echo `date +"%a, %d %b %Y %H:%M:%S %z"` >> debian/changelog deb: changelog dpkg-buildpackage -b -uc debclean: /usr/bin/debclean tags: $(SRCPP) *h ./Makefile -ctags *cpp *h # reformat code with CODE_STYLE=astyle CODE_STYLE_PARMS=--style=linux --indent=tab --indent-col1-comments --indent-preproc-cond style: set -e; for F in $(SRC) $(SRCPP) $(wildcard *.h) ; do $(CODE_STYLE) $(CODE_STYLE_PARMS) $$F ; done clean: ifeq (.version,$(wildcard .version)) $(shell eval expr 0`cat .version` - 1 > .version) endif -rm -f .depends tags $(BUILD_FILE) -rm -fR $(OBJDIR) -rm -fR $(BINDIR) TARFILE=`date +"data-historian-%Y-%m-%d.tar"` distclean: clean debclean rm -f ../$(APP_BASE_NAME)_*.buildinfo rm -f ../$(APP_BASE_NAME)_*.changes distgz: distclean cd .. && tar cf $(TARFILE) data-historian/* && gzip -f $(TARFILE) && cd - # FIL-3174 Added to process Q_OBJECT directive for QObject slots. moc_udp_server.cpp: udp_server.h moc udp_server.h > moc_udp_server.cpp moc_udp_server.o: moc_udp_server.cpp g++ $(CFLAGS) moc_udp_server.cpp -o moc_udp_server.oI'm not the original author of this app but if there are things to cleanup I happy to hear about it.