Ya tengo listo el servidor UDP de echo, la verdad es que las herramientas que nos brindan las librerías Qt son muy potentes y fáciles de usar.
echoserver.h
#ifndef ECHOSERVER_H
#define ECHOSERVER_H
#include "IForm.h"
#include
#include
namespace Ui {
class EchoServer;
}
class EchoServer : public QWidget
{
Q_OBJECT
public:
explicit EchoServer(QWidget *parent = 0);
virtual ~EchoServer();
static const quint16 PORT_MIN;
static const quint16 PORT_MAX;
static const quint16 PORT_DEFAULT;
protected:
QUdpSocket *udpServer;
virtual void putTexts();
virtual void setuid();
static const QString START;
static const QString STOP;
public slots:
void onClickStart();
void readPendingDatagrams();
private:
Ui::EchoServer *ui;
bool started;
};
#endif // ECHOSERVER_H
echoserver.cpp
#include "echoserver.h"
#include "ui_echoserver.h"
#include
const quint16 EchoServer::PORT_MIN = 1;
const quint16 EchoServer::PORT_MAX = 65535;
const quint16 EchoServer::PORT_DEFAULT = 8888;
const QString EchoServer::START = tr("Start");
const QString EchoServer::STOP = tr("Stop");
EchoServer::EchoServer(QWidget *parent) :
QWidget(parent),
ui(new Ui::EchoServer)
{
ui->setupUi(this);
this->udpServer = new QUdpSocket(this);
this->started = false;
putTexts();
setuid();
}
EchoServer::~EchoServer()
{
delete ui;
delete this->udpServer;
qDebug("Delete EchoServer");
}
void EchoServer::putTexts()
{
this->setWindowTitle(tr("Servidor echo UDP"));
ui->lbPort->setText(tr("Port"));
ui->pbStart->setText(tr("Start"));
}
void EchoServer::setuid()
{
setAttribute(Qt::WA_DeleteOnClose);
connect(ui->pbStart, SIGNAL(clicked()),SLOT(onClickStart()));
connect(ui->sldPort, SIGNAL(valueChanged(int)), ui->lcdPort, SLOT(display(int)));
ui->sldPort->setMinimum(EchoServer::PORT_MIN);
ui->sldPort->setMaximum(EchoServer::PORT_MAX);
ui->sldPort->setValue(EchoServer::PORT_DEFAULT);
}
void EchoServer::onClickStart()
{
if(!this->started)
{
qDebug("Server started");
quint16 port = ui->lcdPort->value();
udpServer->bind(port, QUdpSocket::ShareAddress);
connect(udpServer, SIGNAL(readyRead()), this, SLOT(readPendingDatagrams()));
ui->pbStart->setText(STOP);
} else
{
qDebug("Server stoped");
udpServer->close();
ui->pbStart->setText(START);
}
this->started = !this->started;
}
void EchoServer::readPendingDatagrams()
{
qDebug("readPendingDatagrams");
while (udpServer->hasPendingDatagrams())
{
QByteArray datagram;
datagram.resize(udpServer->pendingDatagramSize());
QHostAddress sender;
quint16 senderPort;
udpServer->readDatagram(datagram.data(), datagram.size(),
&sender, &senderPort);
QString str(datagram);
str.append(" from " + sender.toString() + " on " + QDateTime::currentDateTime().toString()+ "\n");
ui->textBrowser->insertPlainText(str);
udpServer->writeDatagram(datagram, sender, senderPort);
}
}
Para iniciar el servidor, simplemente hay que indicar el puerto por el que escuchará y el modo. Además hay que conectar la llegada de paquetes a una función, en este caso la función es readPendingDatagrams() y se ejecutará cada vez que llegue un paquete UDP.
quint16 port = ui->lcdPort->value();
udpServer->bind(port, QUdpSocket::ShareAddress);
connect(udpServer, SIGNAL(readyRead()), this, SLOT(readPendingDatagrams()));
En la función readPendingDatagrams() es donde se realiza el procesamiento de datos y se monta la respuesta para el cliente. En este caso el procesamiento de datos consiste en sacar los datos recibidos por pantalla y la respuesta contiene exactamente los mismos datos que se han recibido.
while (udpServer->hasPendingDatagrams())
{
QByteArray datagram;
datagram.resize(udpServer->pendingDatagramSize());
QHostAddress sender;
quint16 senderPort;
udpServer->readDatagram(datagram.data(), datagram.size(),&sender, &senderPort);
QString str(datagram);
str.append(" from " + sender.toString() + " on " + QDateTime::currentDateTime().toString()+ "\n");
ui->textBrowser->insertPlainText(str);
udpServer->writeDatagram(datagram, sender, senderPort);
}
Como siempre podeis descargar el código desde el svn, para esta versión en concreto desde aquí:
svn checkout http://infobasic.googlecode.com/svn/tags/infobasic-0.0.3 infobasic-read-only