QUdpSocket kann nicht gleichzeitig senden und empfangen?

Alles rund um die Programmierung mit Qt
Antworten
Seikilos
Beiträge: 34
Registriert: 9. Juni 2009 06:43

QUdpSocket kann nicht gleichzeitig senden und empfangen?

Beitrag von Seikilos »

Ist irgendjemandem bekannt, ob in einem Programm zwei QUdpSockets gleichzeitig auf einem Port genutzt werden können? Ich hab ein Socket zum lauschen auf Port x und einen zum Senden auf dem gleichen Port. BindMode ist ShareAddress, aber in der Anwendung wird das Signal des einen nie gefeuert.

Hier ist ein Beispielcode:
MyThread lauscht und MySenderThread schickt etwas

Code: Alles auswählen

#pragma once
#include <QtTest/QtTest>

class MyThread : public QThread
{
    Q_OBJECT
public:


    MyThread()
    {
        foo.bind(QHostAddress::LocalHost,11000,QUdpSocket::ShareAddress);
        connect(&foo, SIGNAL(readyRead()),this, SLOT(rr()));
    }

    void run()
    {
        while(true)
        {
            exec();
           // wait(100);
        }
    }

    QUdpSocket foo;
    public slots:
        void rr()
        {
            // just a dummy
           const QString data = "works";
        }


};


class MySenderThread : public QThread
{

public:

void run()
{
    QUdpSocket qo;
    qo.writeDatagram("fooo",5,QHostAddress::LocalHost, 11000);
    exec();
}
      
};
Aufrufen mittels:

Code: Alles auswählen

 MyThread t;
            t.start();

            MySenderThread st;
            st.start();

            st.wait(10000);
Ich hab am Slot ein Breakpoint, der nie angesprungen wird
solarix
Beiträge: 1133
Registriert: 7. Juni 2007 19:25

Beitrag von solarix »

Ich hab am Slot ein Breakpoint, der nie angesprungen wird
auch nicht 10s nach Programmstart?
Seikilos
Beiträge: 34
Registriert: 9. Juni 2009 06:43

Beitrag von Seikilos »

Mir ist mein Sleep schon klar :)
aber nein, bis zum ende durch garnichts.
Darüber hinaus ist ja nur ein Thread am schlafen, der eigentlich Thread, dessen SLOT angesprungen werden sollte loopt ja vor sich hin und ist aktiv.

Der code ist auch ausführbar (falls jemand Zeit und Interesse hat)
Man braucht nur ne main
solarix
Beiträge: 1133
Registriert: 7. Juni 2007 19:25

Beitrag von solarix »

Darüber hinaus ist ja nur ein Thread am schlafen, der eigentlich Thread, dessen SLOT angesprungen werden sollte loopt ja vor sich hin und ist aktiv.
Klar, aber der slot wird ja nur aktiv, wenn _beide_ was tun.
Der code ist auch ausführbar (falls jemand Zeit und Interesse hat)
ja eben.. bei mir funktioniert der Code.. nach 10s wird das Signal von "MyThread" empfangen.. deshalb habe ich mich gefragt, ob du nur zu ungeduldig warst.. evt. solltest du mal ein komplettes Projekt (inkl pro-File und main.cpp) zur Verfuegung stellen..

[EDIT]
uebringens "lebt" der UDP-Socket von "MyThread" im GUI-Thread.. das SIGNAL "readyRead" wird daher auch von diesem gesendet, nicht aus "MyThread::exec()"..
Seikilos
Beiträge: 34
Registriert: 9. Juni 2009 06:43

Beitrag von Seikilos »

Es funktioniert bei dir so? Wie sieht bei dir der Startcode aus?

Das ganze Ding sieht bei mir so aus:
TEST_UDPCommunicator.h

Code: Alles auswählen

#pragma once

#ifndef TEST_UDP_COMMUNICATOR_H
#define TEST_UDP_COMMUNICATOR_H

#include <QtTest/QtTest>

class MyThread : public QThread
{
    Q_OBJECT
public:


    MyThread()
    {
        foo.bind(QHostAddress::LocalHost,11000,QUdpSocket::ShareAddress);
        connect(&foo, SIGNAL(readyRead()),this, SLOT(rr()));
    }

    void run()
    {
        while(true)
        {
            exec();
           // wait(100);
        }
    }

    QUdpSocket foo;
    public slots:
        void rr()
        {
            // just a dummy
           const QString data = "works"; // BREAKPOINT
        }


};


class MySenderThread : public QThread
{

public:

void run()
{
    QUdpSocket qo;
    qo.writeDatagram("fooo",5,QHostAddress::LocalHost, 11000);
    exec();
}
      
};

class TEST_UDPCommunicator : public QObject
{
    Q_OBJECT

public:
    static const quint16 comPort = 11000;

    private slots:

        void CommunicatorSendTest()
        {
                 
            MyThread t;
            t.start();

            MySenderThread st;
            st.start();

            st.wait(10000);
            
  
        }

  
};#endif
Und eine test_entry.cpp:


Code: Alles auswählen

#include <QtTest/QtTest>


QTEST_MAIN(TEST_UDPCommunicator)

solarix
Beiträge: 1133
Registriert: 7. Juni 2007 19:25

Beitrag von solarix »

Wie sieht bei dir der Startcode aus?
Eine ganz normale main():

Code: Alles auswählen

  QCoreApplication app(argc,argv);
  MyThread t;
  t.start();

  MySenderThread st;
  st.start();  
  st.wait(10000);  

  return app.exec(); // jetzt (wirklich erst jetzt..) wird "readyRead()"  emittet
Das ganze Ding sieht bei mir so aus:
QTEST_MAIN(TEST_UDPCommunicator)
Das kann so nicht funktionieren, weil da das "app.exec()" fehlt. Entweder programmierst du also saubere Threads (so, dass die Klassenmembers _wirklich_ zum Thread gehoeren) oder du musst vor Testende (in der Methode "CommunicatorSendTest()") noch den Eventloop ausfuehren (processEvents()).
Seikilos
Beiträge: 34
Registriert: 9. Juni 2009 06:43

Beitrag von Seikilos »

Mein generelles Problem an der Stelle ist, dass ich mit QtTest die Socket Kommunikation testen will. Dafür brauch ich Slots einer Klasse, die QtTest aufruft. Wie soll man da gescheit eine Thread-Schicht dazu legen und dass dann effizient testen?
solarix
Beiträge: 1133
Registriert: 7. Juni 2007 19:25

Beitrag von solarix »

Dafür gibt es viele Lösungen... prinzipiell benötigst du ja nicht einmal irgendwelche Threads dafür (SIGNALs reichen).

Eine Variante im Test-Slot wäre doch einfach:

1. Server-Instanz erstellen
2. Datagramm versenden (dafür brauchts ja keine eigene Klasse)
3. Eventloop ausführen (z.B. 5s lang)
4. Resultat abfragen ( if (t.hasValidData()) ... )

oder?
Seikilos
Beiträge: 34
Registriert: 9. Juni 2009 06:43

Beitrag von Seikilos »

Aber wie führ ich ein Eventloop aus ohne nen Thread zu haben? hab ja so kein Sleep mit dem ich das System verzögern kann
solarix
Beiträge: 1133
Registriert: 7. Juni 2007 19:25

Beitrag von solarix »

naja.. ich dachte dabei an:

http://doc.trolltech.com/4.5/qtest.html#qWait

ist doch genau das, was du brauchst (eine Pause mit Eventverarbeitung)..
Seikilos
Beiträge: 34
Registriert: 9. Juni 2009 06:43

Beitrag von Seikilos »

Kopf -> Tisch.
Das löst so ziemlich alle meine Probleme ...

Danke für die Hilfe!
Antworten