Seite 1 von 1
QUdpSocket kann nicht gleichzeitig senden und empfangen?
Verfasst: 22. Juni 2009 10:42
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
Verfasst: 22. Juni 2009 13:17
von solarix
Ich hab am Slot ein Breakpoint, der nie angesprungen wird
auch nicht 10s nach Programmstart?
Verfasst: 22. Juni 2009 13:28
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
Verfasst: 22. Juni 2009 14:11
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()"..
Verfasst: 22. Juni 2009 15:10
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)
Verfasst: 22. Juni 2009 16:45
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()).
Verfasst: 22. Juni 2009 17:22
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?
Verfasst: 22. Juni 2009 18:53
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?
Verfasst: 22. Juni 2009 19:54
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
Verfasst: 22. Juni 2009 21:04
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)..
Verfasst: 23. Juni 2009 08:52
von Seikilos
Kopf -> Tisch.
Das löst so ziemlich alle meine Probleme ...
Danke für die Hilfe!