Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 13
  1. #1
    Utente di HTML.it
    Registrato dal
    Mar 2012
    Messaggi
    214

    [C] Read da socket: allocare dinamicamente il buffer

    Ciao a tutti ragazzi, come da titolo devo leggere da una socket un messaggio. Tuttavia le specifiche mi impediscono di fare qualunque tipo di supposizione circa la lunghezza massima del messaggio inviato. Dunque, come potrei fare ad allocare dinamicamente il buffer che passerò alla read per salvare il messaggio? Vi ringrazio in anticipo!

  2. #2
    Utente di HTML.it
    Registrato dal
    Sep 2012
    Messaggi
    707
    Il buffer non lo devi regolare sulla lunghezza massima del messaggio, perché questa potrebbe superare abbondantemente la lunghezza del buffer di lettura del sistema operativo. Devi tu avere nel tuo protocollo un sistema per individuare la fine dei pacchetti, solitamente si scrive nell'header del pacchetto la lunghezza del messaggio.

  3. #3
    Utente di HTML.it
    Registrato dal
    Mar 2012
    Messaggi
    214
    Certo, quando il client fa la write specifico chiaramente la lunghezza del messaggio, ma la

    codice:
    ssize_t read(int fd, void *buf, size_t count);
    prende in ingresso un buffer, che deve essere abbastanza grande da contenere count caratteri. Quando chiamo la read io passo questi parametri:

    codice:
    letti = read(socket, buffer, sizeof(char) );
    e la read mi restituisce il numero di caratteri letti. Il messaggio termina con il carattere newline, quindi se il buffer non contiene "letti" caratteri come faccio a fare una realloc sul buffer che finirò di riempire con una nuova chiamata alla read?
    Non so, magari c'è qualcosa che non ho ben compreso nel funzionamento della read...

  4. #4
    Utente di HTML.it
    Registrato dal
    Sep 2012
    Messaggi
    707
    Non mi sono spiegato bene o non hai ben chiaro il problema. Quando dicevo "solitamente si scrive nell'header del pacchetto la lunghezza del messaggio" non mi riferivo al fatto che "quando il client fa la write specifico chiaramente la lunghezza del messaggio" come da te scritto.

    Se il client fa una write da 100k, non è che la puoi leggere con una singola read da 100k, il buffer di lettura del sistema operativo è di default molto minore.

    Devi fare N volte read. Quante volte allora? Finche arrivi a leggere tutto il pacchetto, di solito si capisce che il pacchetto è finito perché negli header (del TUO protocollo) del pacchetto si invia anche la lunghezza.

  5. #5
    Utente di HTML.it
    Registrato dal
    Mar 2012
    Messaggi
    214
    Dunque, quando creo il pacchetto da inviare inserisco "in testa" un intero che corrisponde alla lunghezza del messaggio, e poi tutto il resto.
    Quando devo prelevarlo, faccio una prima chiamata che mi legge sizeof(int) caratteri, questa sarà la lunghezza del messaggio. Poi un ciclo:

    codice:
    len = read(socket, buffer, sizeof(int) ); 
    while(len != 0){
    len -= read(socket, buffer, sizeof(char) );
    }
    All'uscita dal ciclo buffer conterrà il messaggio. Te lo scrivo per conferma, ti ringrazio per la tua disponibilità non avevo capito cosa intendessi!

  6. #6
    Tip: se inizi ad impostare un protocollo di rete usa interi a dimensione e endian fissati, altrimenti la comunicazione tra architetture diverse diventa un casino.
    Amaro C++, il gusto pieno dell'undefined behavior.

  7. #7
    Utente di HTML.it
    Registrato dal
    Sep 2012
    Messaggi
    707
    Dunque, quando creo il pacchetto da inviare inserisco "in testa" un intero che corrisponde alla lunghezza del messaggio, e poi tutto il resto.
    Ah perfetto allora. Il buffer di lettura dimensionalo su una grandezza media che sai che normalmente leggi. Se mediamente le tue "read" sono da 1k lo dimensioni da 1k, se sono mediamente da 10 bytes, da 10 bytes.

    [EDIT] Se invece stai ricevendo pacchetti grandi Mbytes di dati allora dovresti guardare sul tuo sistema operativo quanto sono grandi i buffer di lettura e basarti su quelli (magari cercando anche su qualche documentazione ufficiale qual'è la grandezza consigliata).

  8. #8
    Utente di HTML.it
    Registrato dal
    Sep 2012
    Messaggi
    707
    Mi era sfuggita questa tua riga:
    read(socket, buffer, sizeof(char) );

    Non devi leggere per sizeof(char) ma per la grandezza del buffer !
    (essendo sizeof(char) = 1, leggeresti al più un carattere alla volta)

    [EDIT] Anche la frase "all'uscita dal ciclo buffer conterrà il messaggio" è sbagliato: a ogni ciclo buffer contiene quello che ha letto SOLO in quella read, sta a te accantonare il risultato delle varie letture ogni volta nel buffer finale (che sarà proprio un altro array diverso da buffer)

  9. #9
    Utente di HTML.it
    Registrato dal
    Mar 2012
    Messaggi
    214
    Si il sizeof(char) era un rimasuglio dell'errore di prima, ti ringrazio per la correzione!

    Non ho tuttavia capito il suggerimento che mi ha dato MItaly...Come posso sapere se mi sono stati inviati dati in little o big endian? E' una cosa dipendente dall'architettura della macchina o sbaglio?


    Edit: in quel ciclo aggiungerò una concatenazione di stringhe, che di volta in volta aggiunge il pezzetto letto al resto!

  10. #10
    Utente di HTML.it
    Registrato dal
    Sep 2012
    Messaggi
    707
    Scusa se ti ho corretto, ma certe volte è difficile capire se è una dimenticanza o un errore. Ciao ciao.

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.