====== 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(); }