0

I have created a server and a client class, which are using UDP protocol. In my Application I have Instantiated 4 objects of Server and 4 objects of client with different Ports.

The problem is I have send data to 4 servers from 4 clients in the same time, But each server Receives it's data only when previous server has finished it's work...

why this is happennig?

this is my code:

Main:

std::thread thread;

client cl1(4235),cl2(4245),cl3(4255),cl4(4265);

void handler()
{
    while(1){

        cl1.SendData("HI1",4230);
        cl2.SendData("HI2",4240);
        cl3.SendData("HI3",4250);
        cl4.SendData("HI4",4260);
        std::this_thread::sleep_for(std::chrono::seconds(50));
    }
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    server s1(4230);
    server s2(4240);
    server s3(4250);
    server s4(4260);
    thread = std::thread(handler);
    return a.exec();
}

Server Class:

class server : public QObject
{
    Q_OBJECT
public :
    server(int port)
    {
        this->port = port;
        udpSocket = new QUdpSocket();
            udpSocket->bind(QHostAddress::LocalHost, port);

            connect(udpSocket, SIGNAL(readyRead()),
                    this, SLOT(readPendingDatagrams()));
    };
   public  slots:
    void readPendingDatagrams()
    {
        while (udpSocket->hasPendingDatagrams()) {
            QByteArray datagram;
            datagram.resize(udpSocket->pendingDatagramSize());
            QHostAddress sender;
            quint16 senderPort;

            udpSocket->readDatagram(datagram.data(), datagram.size(),
                                    &sender, &senderPort);

            //processTheDatagram(datagram);
            QDateTime dateTime;
            dateTime = dateTime.currentDateTime();
            qDebug() << QString::number(dateTime.time().hour()).rightJustified(2, '0') + ":" +//hour
                        QString::number(dateTime.time().minute()).rightJustified(2, '0') + ":" +//minute
                        QString::number(dateTime.time().second()).rightJustified(2, '0');//seconds
            qDebug() << "\t\tdata received from:" << sender.toString() <<":"<<senderPort << "  data:" << datagram;


            std::this_thread::sleep_for(std::chrono::seconds(5));

            qDebug() << QString::number(dateTime.time().hour()).rightJustified(2, '0') + ":" +//hour
                        QString::number(dateTime.time().minute()).rightJustified(2, '0') + ":" +//minute
                        QString::number(dateTime.time().second()).rightJustified(2, '0');//seconds
            qDebug () << "Sending Response";
            udpSocket->writeDatagram(("HI back from" + QString::number(port)).toUtf8(),sender,senderPort);
        }
    };

private:
    QUdpSocket * udpSocket;
    int port;
};

Client Class:

class client : public QObject
{
    Q_OBJECT
   public:
    client(int port) {
        this->port = port;
        udpSocket = new QUdpSocket();
            udpSocket->bind(QHostAddress::LocalHost, port);

            connect(udpSocket, SIGNAL(readyRead()),
                    this, SLOT(readPendingDatagrams()));
    }
    void SendData(QString Data,int serverport)
    {
        QDateTime dateTime;
        dateTime = dateTime.currentDateTime();


        udpSocket->writeDatagram(Data.toUtf8(),QHostAddress::LocalHost,serverport);
        qDebug() << QString::number(dateTime.time().hour()).rightJustified(2, '0') + ":" +//hour
                    QString::number(dateTime.time().minute()).rightJustified(2, '0') + ":" +//minute
                    QString::number(dateTime.time().second()).rightJustified(2, '0')//sec
                 << "\tclient : " <<port << " sending data to server:" << Data;
    }
   public  slots:
    void readPendingDatagrams()
    {
        while (udpSocket->hasPendingDatagrams()) {
            QByteArray datagram;
            datagram.resize(udpSocket->pendingDatagramSize());
            QHostAddress sender;
            quint16 senderPort;

            udpSocket->readDatagram(datagram.data(), datagram.size(),
                                    &sender, &senderPort);

            //processTheDatagram(datagram);
            QDateTime dateTime;
            dateTime = dateTime.currentDateTime();
            qDebug() << QString::number(dateTime.time().hour()).rightJustified(2, '0') + ":" +//hour
                        QString::number(dateTime.time().minute()).rightJustified(2, '0') + ":" +//minute
                        QString::number(dateTime.time().second()).rightJustified(2, '0');//seconds
            qDebug() << "\t\tclient : " <<port << " data received from:" << sender.toString() <<":"<<senderPort << "  data:" << datagram;
        }
    }

private:
    QUdpSocket * udpSocket;
    int port;
};

this is My output data:

"18:50:07"  client :  4235  sending data to server: "HI1"
"18:50:07"  client :  4245  sending data to server: "HI2"
"18:50:07"  client :  4255  sending data to server: "HI3"
"18:50:07"  client :  4265  sending data to server: "HI4"
"18:50:07"
        data received from: "127.0.0.1" : 4235   data: "HI1"
"18:50:07"
Sending Response
"18:50:12"
        data received from: "127.0.0.1" : 4245   data: "HI2"
"18:50:12"
Sending Response
"18:50:17"
        data received from: "127.0.0.1" : 4255   data: "HI3"
"18:50:17"
Sending Response
"18:50:22"
        data received from: "127.0.0.1" : 4265   data: "HI4"
"18:50:22"
Sending Response
Ahmad Afkande
  • 137
  • 2
  • 14
  • So, you're creating a client and a server in the same program? It's possible that might create a blocking condition. Can you try doing this from two programs? Also, I use receiveDatagram instead of readDatagram, and I don't experience what you're reporting. – mzimmers Jul 06 '20 at 16:25
  • I already tried this server class in single server and execute it in multiple processes and it was totally fine, and I have problem in the situation I described above... I will try the function you recomended and let you know the result.thank you. – Ahmad Afkande Jul 06 '20 at 16:57
  • Why are you using threads here at all? All `client` and `server` instances are created on the 'main' thread but are then potentially accessed from both that thread and the secondary thread. That's undefined behaviour. – G.M. Jul 06 '20 at 17:41

1 Answers1

0
std::this_thread::sleep_for(std::chrono::seconds(5)); 

is blocking your current thread. And looking at your main(), this also blocks the main application thread. Therefore, your application will not receive messages from the OS about incoming packets. You should not use sleep functions inside the slots connected to readyRead signals, if you want to process the data in parallel.

smacker
  • 151
  • 6
  • Please look at my code again, the problem is not the thread sleep, these are 4 diferent obejcts and threads, I just put that thread sleep to show my problem. – Ahmad Afkande Jul 06 '20 at 16:59
  • 2
    Re. `"these are 4 diferent obejcts and threads"`: no, there are 4 servers and 4 clients but only 2 threads -- that on which `main` is executing and the globally defined `thread`. – G.M. Jul 06 '20 at 17:41
  • 1
    To amplify on what GM (correctly) said, you have a thread for clients, and another for servers. I'd missed the sleep function on my first read-through, but that explains the intervals you're seeing. You need to explicitly create threads for *each* server/client, then use moveToThread() and thread->start(), again, for each instance. – mzimmers Jul 06 '20 at 17:51
  • @G.M. you were right, I thought each instance of "QUdpSocket" has its own thread, I did what you and mzimmers said about pushing data into another thread to handle them. thank you guys and sorry for late feedback. – Ahmad Afkande Jul 22 '20 at 16:02