Unsolved Qthread in GUI for ServerUDP
-
Hello everybody. I have been strugling with something since several weeks already, as I still havent understood entyrely the behaviour of UDP socket programming and threads.
I must create a server that reads the pending datagram from the client (it is a robot from KUKA). However I need to reply this package within 11 ms with a previously made string taken from an xml file. The package repplied must mirror the timstamp received in the message from the client. So far, so good (at least that is what I think). Using several tutorial, I finally manage to do that code. The problem arises when I try either to read the package received from the client or to write something different in the datagram to send to the client. Whenever I write a line of code that slows down the program a bit, the communication is broken and the robot disconnects as it did not have an answer within that time. Even miore, I cannot create a GUI with working code, because the GUI crashes.
Please help memain.cpp
#include "widget.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); Widget w; w.show(); return a.exec(); }
widget .h
#include <QWidget> #include <QtXml> #include <QTextStream> #include <QString> #include <QMutex> #include "myudp.h" namespace Ui { class Widget; } class Widget : public QWidget { Q_OBJECT public: QString CONST_MAX_NEG_STEP="-0.01"; QString CONST_MAX_POS_STEP="0.01"; QString str_Address; int itg_port; QString SendXML,str_XMLSTATIC,str_dataReceived; explicit Widget(QWidget *parent = 0); ~Widget(); void readXMLFfile(); void findPattern(QString &pattern, QString &value); QString findPatternSensor(QString &pattern,QString &src); private slots: void on_pushButton_connect_clicked(); void on_radioButton_CartesianSelected_toggled(bool checked); void on_radioButton_AxisSelected_toggled(bool checked); void on_lineEdit_port_textEdited(const QString &arg1); void on_lineEdit_address_textEdited(const QString &arg1); void on_pushButton_negativeA6_C_clicked(); void on_pushButton_negativeA2_Y_clicked(); void on_pushButton_negativeA3_Z_clicked(); void on_pushButton_negativeA4_A_clicked(); void on_pushButton_negativeA5_B_clicked(); void on_pushButton_negativeA1_X_clicked(); void on_pushButton_positiveA1_X_clicked(); void on_pushButton_positiveA2_Y_clicked(); void on_pushButton_positiveA3_Z_clicked(); void on_pushButton_positiveA4_A_clicked(); void on_pushButton_positiveA5_B_clicked(); void on_pushButton_positiveA6_Z_clicked(); private: Ui::Widget *ui; bool blnConnect=false; bool blnIsModeCartesian=false,blnIsModeAxis=false; }; #endif // WIDGET_H
WidgetCPP #include "widget.h" #include "ui_widget.h" #include <QUdpSocket> Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget) { ui->setupUi(this); readXMLFfile(); } Widget::~Widget() { delete ui; } void Widget::readXMLFfile(){ // Open a file for reading QFile file("C:/Users/admin/Desktop/clein/Example/RealtimeEthernet/Server_app/ExternalData.xml"); if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) { qDebug() << "Failed to open the file for reading."; } else { QTextStream in(&file); SendXML = in.readAll(); file.close(); } str_XMLSTATIC.append(SendXML); ui->label_XMLtoSend->setText(SendXML); ui->label_Warning->setText("Address Recommended: 192.168.1.11\n " "Port Recommended: 6050"); } void Widget::on_pushButton_connect_clicked() { if(!blnConnect){ blnConnect=true; ui->pushButton_connect->setText("Connecting..."); ui->lineEdit_address->setEnabled(false); ui->lineEdit_port->setEnabled(false); MyUDP server(str_Address,itg_port,str_XMLSTATIC); // MyUDP *server= new MyUDP(str_Address,itg_port,str_XMLSTATIC); // server->moveToThread(server); // server->s } else blnConnect=false; } void Widget::on_radioButton_CartesianSelected_toggled(bool checked) { blnIsModeCartesian=checked; ui->label_Warning->setText("ATTENTION! ROBOT CONTROLLED BY COORDINATES"); ui->label_A1_X->setText("X"); ui->label_A2_Y->setText("Y"); ui->label_A3_Z->setText("Z"); ui->label_A4_A->setText("A"); ui->label_A5_B->setText("B"); ui->label_A6_C->setText("C"); } void Widget::on_radioButton_AxisSelected_toggled(bool checked) { blnIsModeAxis=checked; ui->label_Warning->setText("ATTENTION! ROBOT CONTROLLED BY ANGLES"); ui->label_A1_X->setText("A1"); ui->label_A2_Y->setText("A2"); ui->label_A3_Z->setText("A3"); ui->label_A4_A->setText("A4"); ui->label_A5_B->setText("A5"); ui->label_A6_C->setText("A6"); } void Widget::on_lineEdit_port_textEdited(const QString &arg1) { itg_port=arg1.toInt(); } void Widget::on_lineEdit_address_textEdited(const QString &arg1) { str_Address=arg1; } void Widget::findPattern(QString &pattern, QString &value){ int beginsAt = SendXML.indexOf(pattern)+pattern.size(); int stopsAt = SendXML.indexOf("\"",beginsAt); SendXML.remove(beginsAt,stopsAt-beginsAt); SendXML.insert(beginsAt,value); } QString Widget::findPatternSensor(QString &pattern,QString &src){ int beginsAt= src.indexOf(pattern+pattern.size()); int stopsAt= src.indexOf("\"",beginsAt); QString result=src.mid(beginsAt,stopsAt-beginsAt); return result; } void Widget::on_pushButton_negativeA1_X_clicked() { if(blnIsModeAxis){ QString pattern="A1=\""; QString value=CONST_MAX_NEG_STEP; findPattern(pattern,value); }else if(blnIsModeCartesian) { QString pattern="X=\""; QString value=CONST_MAX_NEG_STEP; findPattern(pattern,value); } ui->label_XMLtoSend->setText(SendXML); } //Modify Axis A2 or Y decrementation void Widget::on_pushButton_negativeA2_Y_clicked() { if(blnIsModeAxis){ QString pattern="A2=\""; QString value=CONST_MAX_NEG_STEP; findPattern(pattern,value); }else if(blnIsModeCartesian) { QString pattern="Y=\""; QString value=CONST_MAX_NEG_STEP; findPattern(pattern,value); } ui->label_XMLtoSend->setText(SendXML); } void Widget::on_pushButton_negativeA3_Z_clicked() { if(blnIsModeAxis){ QString pattern="A3=\""; QString value=CONST_MAX_NEG_STEP; findPattern(pattern,value); }else if(blnIsModeCartesian) { QString pattern="Z=\""; QString value=CONST_MAX_NEG_STEP; findPattern(pattern,value); } ui->label_XMLtoSend->setText(SendXML); } void Widget::on_pushButton_negativeA4_A_clicked() { if(blnIsModeAxis){ QString pattern="A4=\""; QString value=CONST_MAX_NEG_STEP; findPattern(pattern,value); }else if(blnIsModeCartesian) { QString pattern="A=\""; QString value=CONST_MAX_NEG_STEP; findPattern(pattern,value); } ui->label_XMLtoSend->setText(SendXML); } void Widget::on_pushButton_negativeA5_B_clicked() { if(blnIsModeAxis){ QString pattern="A5=\""; QString value=CONST_MAX_NEG_STEP; findPattern(pattern,value); }else if(blnIsModeCartesian) { QString pattern="B=\""; QString value=CONST_MAX_NEG_STEP; findPattern(pattern,value); } ui->label_XMLtoSend->setText(SendXML); } //modify Axis 6 or Orientation C void Widget::on_pushButton_negativeA6_C_clicked() { if(blnIsModeAxis){ QString pattern="A6=\""; QString value=CONST_MAX_NEG_STEP; findPattern(pattern,value); }else if(blnIsModeCartesian) { QString pattern="C=\""; QString value=CONST_MAX_NEG_STEP; findPattern(pattern,value); } ui->label_XMLtoSend->setText(SendXML); } void Widget::on_pushButton_positiveA1_X_clicked() { if(blnIsModeAxis){ QString pattern="A1=\""; QString value=CONST_MAX_POS_STEP; findPattern(pattern,value); }else if(blnIsModeCartesian) { QString pattern="X=\""; QString value=CONST_MAX_POS_STEP; findPattern(pattern,value); } ui->label_XMLtoSend->setText(SendXML); } void Widget::on_pushButton_positiveA2_Y_clicked() { if(blnIsModeAxis){ QString pattern="A2=\""; QString value=CONST_MAX_POS_STEP; findPattern(pattern,value); }else if(blnIsModeCartesian) { QString pattern="Y=\""; QString value=CONST_MAX_POS_STEP; findPattern(pattern,value); } ui->label_XMLtoSend->setText(SendXML); } void Widget::on_pushButton_positiveA3_Z_clicked() { if(blnIsModeAxis){ QString pattern="A3=\""; QString value=CONST_MAX_POS_STEP; findPattern(pattern,value); }else if(blnIsModeCartesian) { QString pattern="Z=\""; QString value=CONST_MAX_POS_STEP; findPattern(pattern,value); } ui->label_XMLtoSend->setText(SendXML); } void Widget::on_pushButton_positiveA4_A_clicked() { if(blnIsModeAxis){ QString pattern="A4=\""; QString value=CONST_MAX_POS_STEP; findPattern(pattern,value); }else if(blnIsModeCartesian) { QString pattern="A=\""; QString value=CONST_MAX_POS_STEP; findPattern(pattern,value); } ui->label_XMLtoSend->setText(SendXML); } void Widget::on_pushButton_positiveA5_B_clicked() { if(blnIsModeAxis){ QString pattern="A5=\""; QString value=CONST_MAX_POS_STEP; findPattern(pattern,value); }else if(blnIsModeCartesian) { QString pattern="B=\""; QString value=CONST_MAX_POS_STEP; findPattern(pattern,value); } ui->label_XMLtoSend->setText(SendXML); } void Widget::on_pushButton_positiveA6_Z_clicked() { if(blnIsModeAxis){ QString pattern="A6=\""; QString value=CONST_MAX_POS_STEP; findPattern(pattern,value); }else if(blnIsModeCartesian) { QString pattern="C=\""; QString value=CONST_MAX_POS_STEP; findPattern(pattern,value); } ui->label_XMLtoSend->setText(SendXML); }
Udp.h #ifndef MYUDP_H #define MYUDP_H #include <QObject> #include <QUdpSocket> #include <QtXml> #include <QTextStream> #include <QDebug> class MyUDP : public QObject { Q_OBJECT QByteArray IPOCnumber; QString SendXML,str_SendXMLSTATIC; QByteArray SendXML_b; QHostAddress sender; quint16 senderPort; QByteArray Buffer,dataReceived; QMutex mtxSender,mtxReceiver; bool blnNewData=false; public: explicit MyUDP(QString str_Address, int itg_Port, QString XMLStatic, QObject *parent = 0); QByteArray getSensorData(); void readFile(QString file); void CopyIPOC(); signals: void started(); public slots: void readPendingDatagram(); void SendUDP(); void writeReceivedData(); private: QUdpSocket *socket; }; #endif // MYUDP_H
#include "myudp.h" #include <thread> MyUDP::MyUDP(QString str_Address, int itg_Port, QString XMLStatic, QObject *parent) { // QHostAddress receiver; // receiver = "192.168.1.11"; //Kuka computer 192.198.1.101 str_SendXMLSTATIC=XMLStatic; socket = new QUdpSocket(this); bool blnOk=socket->bind(QHostAddress(str_Address),itg_Port); if(blnOk){ connect(socket, SIGNAL(readyRead()),this,SLOT(readPendingDatagram())); qDebug() <<"Socket binded"; } else{ qDebug()<<"could not connect to the socket"; } Buffer.resize(1000); } void MyUDP::readPendingDatagram(){ if(socket->hasPendingDatagrams()){ //Buffer.resize(socket->pendingDatagramSize()); socket->readDatagram(Buffer.data(),Buffer.size(),&sender,&senderPort);//collects information CopyIPOC(); SendUDP(); } } void MyUDP::readFile(QString file){ SendXML = file; } QByteArray MyUDP::getSensorData(){ return Buffer; } void MyUDP::CopyIPOC(){ //Reading IPOC positions int beginsAt = Buffer.indexOf("<IPOC>") + 6; int stopsAt = Buffer.indexOf("</IPOC>"); //Copying IPOC IPOCnumber = Buffer.mid(beginsAt,stopsAt-beginsAt); //finding where to insert if(!blnNewData)SendXML_b.append(str_SendXMLSTATIC); beginsAt = SendXML_b.indexOf("<IPOC>") + 6; stopsAt = SendXML_b.indexOf("</IPOC>"); SendXML_b.remove(beginsAt,stopsAt-beginsAt); SendXML_b.insert(beginsAt,IPOCnumber); } void MyUDP::SendUDP(){ // qDebug() << "Message senT: " << SendXML_b; socket->writeDatagram(SendXML_b, sender, senderPort); SendXML_b.clear(); } void MyUDP::writeReceivedData(){ }
-
@Alucard said in Qthread in GUI for ServerUDP:
However I need to reply this package within 11 ms with a previously made string taken from an xml file.
How do you assure this requirement is met?
-
Hi
Regarding crashing the GUI.
Use the debugger. place break point and single step to find the spot it crashes.