Problem in QUdpSocket
-
this is the code of program :
@#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QRadioButton>MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{ui->setupUi(this); //******** création des sockets *********** talkerSocket = new QUdpSocket(this); listenSocket = new QUdpSocket(this); if (!listenSocket->bind(QHostAddress::Any, 8888)) { qDebug("Impossible de créer le socket en écoute"); exit(EXIT_FAILURE); } qDebug() <<"Connecting..."; talkerSocket->connectToHost(QHostAddress::LocalHost,8888); if(!talkerSocket->waitForConnected(1000)) { qDebug() <<"ERROR : "<<talkerSocket->errorString(); } ui->statusBar->showMessage("connecté"); QObject::connect(listenSocket, SIGNAL(readyRead()), this, SLOT(processPendingDatagrams()));
}
MainWindow::~MainWindow()
{
delete ui;
}void MainWindow::on_alerte_clicked()
{QByteArray datagram; QString msg = "alert"; datagram.append(msg); if (talkerSocket->writeDatagram(datagram, senderAddress, senderPort) == -1) { qDebug("Émission du message impossible"); talkerSocket->close(); exit(EXIT_FAILURE); } datagram.clear(); qDebug()<<"envoie succee";
}
void MainWindow::processPendingDatagrams()
{
while (listenSocket->hasPendingDatagrams()) {
qDebug()<<"il existe un datagrame";QByteArray datagram; datagram.resize(listenSocket->pendingDatagramSize()); if (listenSocket->readDatagram(datagram.data(), datagram.size(), &senderAddress, &senderPort) == -1) { listenSocket->close(); exit(EXIT_FAILURE); } QString msge = datagram.data(); qDebug() << "Depuis : " << senderAddress.toString() << ':' << senderPort; qDebug() << "Message : " << msge; ui->label->setText(tr("Depuis : %1: %2") . arg(senderAddress.toString()) . arg(senderPort)); qDebug()<<"reception succé"; datagram.clear(); }
}@
-
Udp is a connectionless socket so I believe that the socket must be bound to a port for it to be able to send and receive. Unless Qt has some other implementation of the connectToHost() method, your not going to be able to send out that socket until it is bound.
Also, if your binding to the same port, be prepared to get an echo back when you send, it might be better to bind to a different ports, since you know which ones you are sending and receiving on.
If your sending udp messages locally on the machine, why not use a QLocalSocket? It has a great API.
-
In this instanceConnectToHost() is unneeded because you are not using the QIODevice interface, just writeDatagram(). bind() is required on the receiving end only.
In your code you are confusing the address/port you wish to send to with the address/port the datagram was received from.
The first writeDatagram() goes to senderAddress/senderPort. It is not clear where you initialise senderAddress but I am assuming it is localhost. When that datagram is received it comes from localhost and a random port. The way you use readDatagram() you overwrite senderPort with that random port number. Your next writeDatagram() goes to that random port and is not received.
Here is a complete example that writes a datagram to itself once a second (quits after 10).
@
#include <QCoreApplication>
#include <QUdpSocket>
#include <QHostAddress>
#include <QTimer>class UDPTest: public QObject
{
Q_OBJECT
QUdpSocket *talkerSocket;
QUdpSocket *listenSocket;
QHostAddress remoteAddress;
int listenPort;public:
UDPTest(QObject *p = 0):
QObject(p),
remoteAddress("127.0.0.1") ,
listenPort(8888)
{
talkerSocket = new QUdpSocket(this);
listenSocket = new QUdpSocket(this);if (!listenSocket->bind(QHostAddress::Any, listenPort)) { qDebug("Impossible de créer le socket en écoute"); exit(EXIT_FAILURE); } QObject::connect(listenSocket, SIGNAL(readyRead()), SLOT(processPendingDatagrams())); QTimer *t = new QTimer(this); connect(t, SIGNAL(timeout()), SLOT(doSend())); t->setInterval(1000); t->start(); }
private slots:
void doSend() {
QByteArray datagram("Tick");
if (talkerSocket->writeDatagram(datagram, remoteAddress, listenPort) == -1) {
qDebug("Émission du message impossible");
talkerSocket->close();
exit(EXIT_FAILURE);
}
qDebug()<<"envoie succee";
}void processPendingDatagrams() { while (listenSocket->hasPendingDatagrams()) { qDebug()<<"il existe un datagrame"; QByteArray datagram; datagram.resize(listenSocket->pendingDatagramSize()); QHostAddress senderAddress; // << these are local quint16 senderPort; if (listenSocket->readDatagram(datagram.data(), datagram.size(), &senderAddress, &senderPort) == -1) { listenSocket->close(); exit(EXIT_FAILURE); } QString msge = datagram.data(); qDebug() << "Depuis : " << senderAddress.toString() << ':' << senderPort; qDebug() << "Message : " << msge; qDebug()<<"reception succé"; } }
};
int main(int argc, char **argv)
{
QCoreApplication app(argc, argv);
UDPTest test;
QTimer::singleShot(10000, qApp, SLOT(quit()));
return app.exec();
}
#include "main.moc"
@