Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. International
  3. Italian
  4. Comunicare via TCP e leggere dati di una Struct
Forum Updated to NodeBB v4.3 + New Features

Comunicare via TCP e leggere dati di una Struct

Scheduled Pinned Locked Moved Solved Italian
7 Posts 2 Posters 2.8k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • B Offline
    B Offline
    Bruschetta
    wrote on last edited by
    #1

    Ho il seguente problema,
    sono collegato ad un device che in linguaggio C crea un server TCP il quale risponde ai messaggi del client inviando una struttura con dei dati. Il server è questo:

    typedef struct
    {
       long quota1;
       long quota2;
       long flags;
       long progressivo;
    }DATI;
     
    //----------------------------------------------
    // server tcp port 5000
    //----------------------------------------------
    void task5000(void)
    {
       static int i5000=0;      //n. servers aperti contemporaneamente
       FILE *f=0;               //connessione TCP  (tipo ETH_FILE)
       char buffer[100];        //buffer ricezione dati
       DATI dati;               //dati da inviare al client
       int nbytes;              //n. di bytes arrivati dal client 
       if (i5000 < 3)           //accetta al massimo 4 clients contemporanei
       {
          f=fopen("TCP:SERVER",5000);  //open server porta 5000 
          if(f)                        //se connessione TCP avvenuta ...
          {
             i5000++;              //incrementa n. connessioni aperte
             MB1=i5000;            //led 
             while(!eof(f))        //fino a quando connessione attiva ...
             {
                if(nbytes=fread(buffer,80,1,f))     //se vi sono dati dal client li legge e ...
                {
                   dati.quota1=touch_x;             //prepara risposta
                   dati.quota2=touch_y;    
                   dati.flags=touch_premuto;
                   dati.progressivo++;
                   fwrite(&dati,sizeof(dati),1,f);  //invia risposta al client
                }
             }
             fclose(f);                 //a fine connessione chiude connessione
             i5000--;                   //decrementa n. connessioni attive
          }
       }
       MB1=i5000;                    //led 
       remove_task(THIS_TASK);       //chiude il task del server tcp
       while(1);                     //attende chiusura
    }
    

    Il mio client QT stabilisce la connessione e riceve i dati ma non so in che maniera trattare (leggere)i dati della struttura. Avete qualche consiglio / guida da darmi?

    Client

    
    TCPClientGui::TCPClientGui(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::TCPClientGui)
    {
        ui->setupUi(this);
        socket=new QTcpSocket(this);
        ui->port->setRange(0,9999);
        ui->port->setValue(5000);
        ui->trace->setReadOnly(true);
    
        connect(socket, SIGNAL(connected()), this, SLOT(connected()));
        connect(socket, SIGNAL(readyRead()), this, SLOT(readServer()));
    }
    
    TCPClientGui::~TCPClientGui()
    {
        delete ui;
    }
    
    void TCPClientGui::connectToHost(){
        socket->connectToHost(QHostAddress(ui->host->text()), ui->port->value());
    }
    
    void TCPClientGui::connected(){
        socket->write(QString("Hello Server").toLatin1());
        ui->trace->append("Connected");
        socket->waitForBytesWritten();
    }
    
    void TCPClientGui::sendMessage(){
        socket->write(QString(ui->message->text()).toLatin1());
        ui->trace->append("Ho inviato il messaggio");
        socket->waitForBytesWritten();
    }
    
    void TCPClientGui::readServer(){
        ui->trace->append(socket->readAll());
        qDebug() << "Ho letto: " << socket->readAll().toHex();
    }
    
    void TCPClientGui::on_sendMessage_clicked()
    {
         this->sendMessage();
    }
    
    void TCPClientGui::on_control_clicked()
    {
        this->connectToHost();
    }
    
    
    1 Reply Last reply
    0
    • VRoninV Offline
      VRoninV Offline
      VRonin
      wrote on last edited by VRonin
      #2

      Non ho modo di provarla ma questo dovrebbe andare.

      typedef struct
      {
         long quota1;
         long quota2;
         long flags;
         long progressivo;
      }DATI;
      void TCPClientGui::readServer(){
      while(socket->bytesAvailable() >= sizeof(DATI)){
      const QByteArray raw = socket->read(sizeof(DATI));
      const DATI* const rawData = reinterpret_cast<const DATI*>(raw.constData());
      qDebug() << rawData->quota1 << rawData->quota2<< rawData->flags << rawData->progressivo;
      }
      }
      

      NOTA: se server e client sono compilati con compilatori diversi e/o girano su sistemi diversi il tutto potrebbe andare a schifio in quanto sizeof(DATI) potrebbe essere diverso. Il server non e' fatto granche' bene ma suppongo tu non possa farci nulla

      Edit: aggiunti const mancanti

      "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
      ~Napoleon Bonaparte

      On a crusade to banish setIndexWidget() from the holy land of Qt

      B 1 Reply Last reply
      1
      • VRoninV VRonin

        Non ho modo di provarla ma questo dovrebbe andare.

        typedef struct
        {
           long quota1;
           long quota2;
           long flags;
           long progressivo;
        }DATI;
        void TCPClientGui::readServer(){
        while(socket->bytesAvailable() >= sizeof(DATI)){
        const QByteArray raw = socket->read(sizeof(DATI));
        const DATI* const rawData = reinterpret_cast<const DATI*>(raw.constData());
        qDebug() << rawData->quota1 << rawData->quota2<< rawData->flags << rawData->progressivo;
        }
        }
        

        NOTA: se server e client sono compilati con compilatori diversi e/o girano su sistemi diversi il tutto potrebbe andare a schifio in quanto sizeof(DATI) potrebbe essere diverso. Il server non e' fatto granche' bene ma suppongo tu non possa farci nulla

        Edit: aggiunti const mancanti

        B Offline
        B Offline
        Bruschetta
        wrote on last edited by
        #3

        @VRonin Grazie mille Ronin , proverò la tua soluzione.
        Si purtroppo per il server non posso farci nulla, mi è stato consegnato così.

        Anche la tua Nota è corretta.. Vediamo cosa salta fuori!

        B 1 Reply Last reply
        0
        • B Bruschetta

          @VRonin Grazie mille Ronin , proverò la tua soluzione.
          Si purtroppo per il server non posso farci nulla, mi è stato consegnato così.

          Anche la tua Nota è corretta.. Vediamo cosa salta fuori!

          B Offline
          B Offline
          Bruschetta
          wrote on last edited by
          #4

          Perfetto funziona, ho solo dovuto sistemare il cast
          DATI* rawData = const_cast<DATI*>(reinterpret_cast<const DATI*>(raw.constData()));

          1 Reply Last reply
          0
          • VRoninV Offline
            VRoninV Offline
            VRonin
            wrote on last edited by
            #5

            io eviterei const_cast dovrebbe essere l'ultima risorsa e qui hai alternative.

            basta dichiarare const DATI* rawData invece di DATI* rawData

            "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
            ~Napoleon Bonaparte

            On a crusade to banish setIndexWidget() from the holy land of Qt

            B 1 Reply Last reply
            1
            • VRoninV VRonin

              io eviterei const_cast dovrebbe essere l'ultima risorsa e qui hai alternative.

              basta dichiarare const DATI* rawData invece di DATI* rawData

              B Offline
              B Offline
              Bruschetta
              wrote on last edited by Bruschetta
              #6

              @VRonin Ho un'ulteriore domanda sempre sull'esempio precedente.
              Vorrei testare la possibilità che la connessione cada.

              Per fare questo ho fatto così nel ciclo di ascolto:

              bool connected=false;
              while(1){
                      //Se la connessione esiste invio il messaggio
                      connected = (socket->state() == QTcpSocket::ConnectedState);
                      if(connected){
                          //Invio un messaggio di "polling" per ricevere le coordinate dal server
                          sendMessage();
                          delay(250);
                          //La connessione non esiste/è caduta, la ripristino
                      }else{
                         qDebug() << "Stato diverso: abort ";
                         socket->abort();
                         socket->connectToHost(QHostAddress("192.168.0.12"), 5000);
                     }
                  }
              

              Ovviamente mi va a rifinire sempre nell'else ma non ho capito perchè dato che se elimino il controllo la connessione va che è una meraviglia e i messaggi vanno e vengono tranquillamente.

              Che cosa non ho capito di questo comando? socket->state() == QTcpSocket::ConnectedState

              Grazie

              EDIT: Mi rispondo da solo. Il delay troppo basso.

              1 Reply Last reply
              0
              • VRoninV Offline
                VRoninV Offline
                VRonin
                wrote on last edited by
                #7

                molto probabilmente e' perche' QTcpSocket e' in QTcpSocket::BoundState comunque puoi semplicemente connetere uno slot a disconnected ivece di fare un loop infinito che ti interferisce con l'event loop di Qt

                connect(socket,&QTcpSocket::diconnected,[&]()->void{socket->abort();
                           socket->connectToHost(QHostAddress("192.168.0.12"), 5000);});
                

                "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                ~Napoleon Bonaparte

                On a crusade to banish setIndexWidget() from the holy land of Qt

                1 Reply Last reply
                1

                • Login

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • Users
                • Groups
                • Search
                • Get Qt Extensions
                • Unsolved