Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 13
  1. #1
    Utente di HTML.it L'avatar di boots
    Registrato dal
    Oct 2012
    Messaggi
    1,626

    [C++/QT] Consiglio su socket

    Ciao a tutti,
    Avrei un piccolo dubbio riguardo i socket con QT.
    Vi spiego la mia situazione:
    Dovrei creare un server che invia ogni secondo dei dati(360 byte) ad i client connessi.
    Dato che i client connessi si contano sulle dita di una mano (il 90% delle volte sarà uno solo)
    opterei per un server single thread.

    Mi salvo i socket dei client che si connettono in una struttura dati (dizionario, vettore o quel che sia) e poi quando devo inviare i dati li prendo ad una ad uno e faccio l'invio.

    Il mio dubbio sta sulla readyRead(), lato client: una volta avvenuto l'evento, quando farò la read prenderò tutti i 360byte? o conviene leggere un byte la volta e inserirlo in un buffer(char[]), fermandomi quando raggiungo i 360byte letti?

    Inoltre questa stringa di 360byte sono in realtà 45 double, quale sarebbe il modo migliore per ri-trasformarli in double?

    se faccio così:
    codice:
    char buffer[360];
    double* ptr;
    // Leggo i 360 byte dal socket
    ptr = (double*)buffer;
    E' corretto?

    Grazie

  2. #2
    Utente di HTML.it
    Registrato dal
    Sep 2012
    Messaggi
    707
    Il mio dubbio sta sulla readyRead(), lato client: una volta avvenuto l'evento, quando farò la read prenderò tutti i 360byte? o conviene leggere un byte la volta e inserirlo in un buffer(char[]), fermandomi quando raggiungo i 360byte letti?
    Non c'è mai nessuna garanzia di quanti bytes leggerai ogni volta con:
    read(int fd, void *buf, size_t count);
    Ne leggerai al massimo "count".
    Devi fare un loop fino a quando hai letto 360 bytes, ogni volta riarrangiando il secondo e terzo argomento,
    Ponendo la variabile "n" a quanti bytes hai letto fino a questo momento, imposti
    di modo da riempire buf alla posizione giusta (cambi l'indice) e impostando count a 360 - n.
    Esempio:

    codice:
    char buf[360];
    int n, len = 0;
    
    for (n = 0; n < 360; n += len)
        len = recv(fd, &buf[n], 360 - n);

  3. #3
    Utente di HTML.it L'avatar di boots
    Registrato dal
    Oct 2012
    Messaggi
    1,626
    Grazie per la risposta...
    Comunque credo che le cose siano più complicate a causa di QT.

    Se ricevessi 200/360 byte e poi i restanti 160 un nuovo evento readyRead partirebbe.
    In ogni caso, un idea su come fare me la son fatta
    codice:
    private:
       qint64 byteRead;
       char buffer[360];
       QTcpSocket *s;
    
    // Connesso con il segnale readyRead di s
    void read(){
       qint64 len = s->read(&buffer[byteRead], 360-byteRead);
       byteRead += len;
       if(byteRead == 360) {
            this->saveData();
            byteRead=0;
       }
    }
    Spero solo che i dati inviati non si "mescolino", viso che invio blocchi di 360byte ogni secondo.E' possibile che succeda questo?:
    Server invia BLOCCO1(360)
    Server invia BLOCCO2(360)

    Client riceve BLOCCO1(200);
    Client riceve BLOCCO2(200);
    Client riceve BLOCCO1(160);
    Clientriceve BLOCCO2(160);

  4. #4
    Utente di HTML.it
    Registrato dal
    Sep 2012
    Messaggi
    707
    Spero solo che i dati inviati non si "mescolino", viso che invio blocchi di 360byte ogni secondo.
    Ci mancherebbe che i dati si mescolino, stiamo parlando del tcp spero?

    Riguardo al fatto che tu usi le funzioni delle QT, certamente dovrai guardare alle funzionalità che ti offre l'API,
    e sicuramente ci saranno esempi più specifici del mio.
    Io in effetti ho inteso la tua domanda con un carattere più generale sul funzionamento della "read".

  5. #5
    Utente di HTML.it L'avatar di boots
    Registrato dal
    Oct 2012
    Messaggi
    1,626
    Si si è tcp

    Adesso la mia unica preoccupazione è che una parte dei 360 byte del primo blocco non impieghi più tempo ad arrivare della prima del secondo blocco (e quindi leggo mezzo primo blocco e mezzo secondo)...ma se dici che non è possibile, mi fido

  6. #6
    Utente di HTML.it
    Registrato dal
    Sep 2012
    Messaggi
    707
    Sull'ordine posso citare l'rfc 793 (http://tools.ietf.org/html/rfc793):
    The TCPs include control information in the segments which they use to ensure reliable ordered data transmission.
    o Wikipedia:
    TCP provides reliable, ordered delivery of a stream of octets

  7. #7
    Utente di HTML.it L'avatar di boots
    Registrato dal
    Oct 2012
    Messaggi
    1,626
    Ok...grazie tante per il supporto

  8. #8
    Utente di HTML.it
    Registrato dal
    Sep 2012
    Messaggi
    707
    Mi spiace che avrei dovuto risponderti in modo più pertinente alle QT, mi è un po' sfuggito il contesto.
    Vedo ora che puoi usare un bytesAvailable() prima ancora di fare socket->read().
    Quindi forse dovresti fare un loop dentro la tua "void read" fintanto che non hai consumato quei bytes disponibili.
    Ciao.

  9. #9
    Utente di HTML.it L'avatar di boots
    Registrato dal
    Oct 2012
    Messaggi
    1,626
    Non preoccuparti...alla fine il problema è generale.

    Anche con bytesAvaiable, resterebbe l'incognita di readyRead() che se nonn ho capito male partirebbe ogni volta che arrivano dati.
    Al massimo potrei cambiare così
    codice:
    void read(){
       if(s->bytesAvaiable() < 360)
           return;
       qint64 len = s->read(buffer, 360);
       this->saveData();
    }
    Giusto?

  10. #10
    Utente di HTML.it
    Registrato dal
    Sep 2012
    Messaggi
    707
    Non mi sembra tanto giusto il tuo codice, mi dà l'idea che consumi cicli cpu inutilmente con tutte quelle return, per quello ti dicevo di un loop.

    Riguardo al fatto che readyRead venga invocato mentre sei dentro la funzione non credo proprio, sarebbe una implementazione orribile. Non ho trovato ancora una documentazione ufficiale ma per esempio qui [http://www.qtcentre.org/threads/1731...ading-the-data] dice "Qt signal/slots mechanism grants that the readyRead() connected slots won't be called in a overlapped fashion."

    Quando la tua funzione ritorna, sola allora verrà richiama, offrendoti un buffer da cui leggere senza i bytes che hai letto l'ultima volta.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.