====== Semplice echo server con client tcp ======
Autore: **//Fabio Di Matteo//** \\ Ultima revisione: **//14/03/2014//** \\ \\
Lo scopo di questo articolo è quello di realizzare un (molto) semplice echo server con client entrambi di tipo tcp. L'esempio che segue è stato compilato senza problemi sia con le qt 5.x che le qt 4.8 . \\
Innanzi tutto cominciamo con il dire che i socket in qt vengono correttamente usati tramite alcuni segnali (SIGNAL) che notificano un particolare evento. Come per esempio l'avvenuta connessione di un client su un server, oppure la disconnessione o ancora la ricezione di dati da parte di un client etc... Nel nostro esempio useremo soltanto un paio di segnali giusto per far funzionare lo scambio dei dati. \\ \\
// Output della nostra applicazione: // \\ \\
**Client**
Client partito...
Connesso al server...
"Ciao Client inserisci una stringa:"
->ciao
ciao
**Server**
Server partito.
ciao
Di seguito il codice del client e del server abbondantemente commentato.
===== Server =====
Il server che andremo a scrivere è un server bloccante, ovvero capace di accettare una sola connessione per volta. Per compilare i progetti diamo i soliti **qmake** e **make** nel terminale dalla cartella del progetto server o quella del client.
**Server.pro**
QT += core
QT -= gui
QT += network
TARGET = Server
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
SOURCES += main.cpp \
myserver.cpp
HEADERS += \
myserver.h
**myserver.h**
#ifndef MYSERVER_H
#define MYSERVER_H
#include
#include
#include
#include
class MyServer : public QObject
{
Q_OBJECT
public:
explicit MyServer(QObject *parent = 0);
signals:
public slots:
void newConnection();
private:
QTcpServer *server;
};
#endif // MYSERVER_H
**myserver.cpp**
#include "myserver.h"
#include //only for QByteArray object
#include
#include
MyServer::MyServer(QObject *parent) :
QObject(parent)
{
server = new QTcpServer(this);
connect(server, SIGNAL(newConnection()),this, SLOT(newConnection()) ); //non appena arrivano nuove connessioni esegue newConnection()
if (!server->listen(QHostAddress::Any, 1234)) //mette in ascolto il server sulla porta 1234 se possibile
{
qDebug()<< "Il Server non puo' partire.";
}else{
qDebug()<< "Server partito.";
}
}
void MyServer::newConnection()
{
QTcpSocket *socket= server->nextPendingConnection(); // "Aggancio" il socket al server (bind)
socket->write("Ciao client! Inserisci una stringa:") ; //mando un messaggio di benvenuto al client
socket->flush();
QByteArray mykeypass; //Array di byte utilizzato per scambiare dati con il client
bool quit=false; //una varibile booleana per uscire dal while
while(quit==false)
{
if (socket->waitForReadyRead(3000)) //aspetto che venga emesso nel client il segnale readyRead()
{
//Leggo e mostro cosa ha scritto il client
mykeypass= socket->readLine();
qDebug()<<""<< mykeypass;
socket->flush();
//Invio al client l'eco di quello che ha scritto
socket->write(mykeypass);
socket->flush();
}
if (strcmp(mykeypass.data(),"quit")==0) //Mi serve solo per uscire dal programma
{
quit=true; qDebug()<<"Esco...";
socket->close();
qApp->exit();
}
}
}
**main.cpp**
#include
#include "myserver.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
MyServer Server;
return a.exec();
}
===== Client =====
Un semplice client che legge il messaggio di benvenuto del server, poi chiede all'utente di scrivere qaulcosa, lo invia al server e ne attende la risposta. Dopodicche richiede di nuovo l'input dell'utente, lo invia al server e così via ... \\ Per compilare i progetti diamo i soliti **qmake** e **make** nel terminale dalla cartella del progetto server o quella del client.
Client.pro
QT += core
QT += network
QT -= gui
TARGET = Client
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
SOURCES += main.cpp \
myclient.cpp
HEADERS += \
myclient.h
**myclient.h**
#ifndef MYCLIENT_H
#define MYCLIENT_H
#include
#include
#include
class myClient : public QObject
{
Q_OBJECT
public:
explicit myClient(QObject *parent = 0);
signals:
public slots:
void myread(); //segnali spiegati in myclient.cpp
void onConnected();
private:
QTcpSocket *socket; //socket utilizzato per la connessione
QByteArray data; //array per scambiare messaggi con il server
};
#endif // MYCLIENT_H
**myclient.cpp**
#include "myclient.h"
#include
myClient::myClient(QObject *parent) :
QObject(parent)
{
socket= new QTcpSocket(this);
socket->connectToHost("192.168.1.2", 1234); //mi connetto al server(ip e porta)
connect(socket, SIGNAL(connected()),this,SLOT(onConnected())); //quando si connette esegue onConnect()
connect(socket, SIGNAL(readyRead()),this,SLOT(myread())); //quando la connessione è pronta esegue myread()
qDebug()<<"Client partito...";
}
void myClient::onConnected()
{
qDebug()<<"Connesso al server...";
}
void myClient::myread()
{
data=socket->readLine(); //Catturo il msg di benvenuto del server
socket->flush(); // e lo mostro.
qDebug()<"; //Catturo l'input da tastiera
std::cin >> data.data();
socket->write(data); //Mando al server quello che ho scritto
socket->waitForBytesWritten(); //aspettando che arrivi correttamente.
socket->flush();
socket->waitForReadyRead(); //Aspetto che la risposta del server
data=socket->readLine(); //sia disponibile e la leggo
socket->flush();
qDebug()<<""<
**main.cpp**
#include
#include "myclient.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
myClient mClient;
return a.exec();
}