Problema client/server

di il
30 risposte

30 Risposte - Pagina 2

  • Re: Problema client/server

    Una connessione TCP (la cosidetta socket) e' una brutta bestia.
    Ci sono un po' di elucubrazioni mentali che uno si deve fare:

    1) su una socket si inviano SOLO BYTE e si ricevono SOLO BYTE. Qualunque cosa si vuole inviare, deve essere convertito prima in una sequenza di byte.
    2) la connessione e' stream oriented: vengono inviati una sequenza di byte, vengono ricevuti una sequenza di byte
    3) mentre l'invio viene fatto a blocchi di byte coerenti con la dimensione dell'oggetto da inviare (char->1 byte, short->2 byte, double->8 byte), da nessuna parte e' assicutao che in ricezione vegano ricevuti pacchetti della dimensione corretta.

    Piu' specificatamente: e' una decisione degli apparati di rete, della scheda di rete del sender e della scheda di rete del receiver decidere come suddividere o concatenare i blocchetti di byte inviati e ricevuti

    Uno invia 8 byte, ma in ricezione gli possono arrivare 8, 4+4, 5+3, o qualunque altra suddivisione l'infrastruttura di rete decida di utilizzare.

    Ma ovviamente e' anche piu' peggio di cosi': piu' invii possono essere ricevuti in un'unico blocco.

    Quindi in ricezione, non si deve solo attendere una certa quantita' di byte, ma ci si deve assicurare che siano effettivamente arrivati, e se non ce en sono abbastanza, salvare quelli che sono arrivati, concatenandoli con quelli precedenti se ce ne sono, e continuare a attendere. Se ce ne sono di piu', consumare solo quelli che servono e tener traccia di quelli che avanzano.

    Classico esempio una stringa bella lunga: non si deve solo inviare i byte della stringa, ma per prima cosa la lunghezza, in modo che in ricezione si sappia quanto byte devono essere letti per avere la stringa completa.

    Ovviamente al peggio non c'e' fine: ci si deve assicurare anche di fare un flush dellla connessione per forzare l'invio dei dati che altrimenti rimarrebbero in attesa dal lato del sender. Il flush e' automatico quando uno chiude la connessione TCP.

    A partire da queste considerazioni, un buon approccio al problema e' quello di implementare una libreria intermedia che converte la connessione TCP da stream oriented a message oriented. Cioe':

    1) il sender invia messaggi, cioe' blochetti di byte di una certa lunghezza
    2) il receiver riceve messaggi, cioe' blochhetti di byte di una certa lunghezza.

    La libreria mettera' a disposizione primitive tipo:

    void send(char* message, in length)
    int receive(char *messageBuffer)
    int onReceived(char *messageBuffer)

    e si smazza tutta la logica del come convertire il messaggio in uno stream TCP (invia prima la lunghezza del messaggio e poi i byte del messaggio, riceve prima la lunghezza del messaggio e poi il corpo del messaggio)

    Fatto questo, tutto diventa moooooooolto piu' semplice. Almeno per questo tipo di applicazioni.
  • Re: Problema client/server

    In effetti, per i motivi di cui ha scritto migliorabile, non è detto che tu riceva subito tutto quello che invii.

    Devi attendere (usando un ciclo e aggiungendo i byte ricevuti nel buffer) che siano ricevuti tutti i dati inviati. Dato che invii una stringa, devi inviare anche il NULL finale per far comprendere al codice che riceve che i dati sono terminati e solo a quel punto può usare la atof.

    Nel caso in cui tu utilizzassi l'invio del double (senza buffer), premettendo che i due sistemi utilizzino lo stesso formato di double, devi attendere sempre e solo 8 byte, senza terminatore e avrai il valore corretto.
  • Re: Problema client/server

    Chiedo scusa in anticipo per l'antipatia ma..come posso risolvere?praticamente che posso fare??devo lavorare sulla write o sulla read?
    so di essere insistente ma se non risolvo questo problema,non possso andare avanti col progetto..
  • Re: Problema client/server

    Lavori sulla read inserendola in un ciclo. Te l'ho scritto.
  • Re: Problema client/server

    Invece del crossposting che ne facciamo? dall'altra parte hanno già chiuso la discussione, chiudiamo anche quà?
  • Re: Problema client/server

    Ho provato usando la fullwrite e la fullread ma il server non riceve proprio più..
    Adesso sto facendo controlli sulla write e la read.
    
    if ((d=write(sockfd, buffer, strlen(buffer))) <0)
        {
        perror("write error");
        exit(-1);
        }
    printf("\nWRITE %d\n",d);
    
    Stessa cosa per la read e dichiarando d come un intero.Mi dovrebbero dare lo stesso valore in quanto mi restiruiscono numero di elementi scritti/letti.Giusto?Ma il valore della write è sempre maggiore della read..Aiuto!!
  • Re: Problema client/server

    skynet ha scritto:


    Invece del crossposting che ne facciamo? dall'altra parte hanno già chiuso la discussione, chiudiamo anche quà?
    chiedo scusa per il crossposting..eviterò da questo momento in poi..ma ho veramente bisogno di risolvere sto problema..forse sono incapace io,ma sono due giorni che le provo tutte
  • Re: Problema client/server

    Per usare la sequenza \r\n devi usae la recv e la send.
    togli \r\n se vuoi usare write e read.
    dato che trasformi la vaiabile double in una stringa tramite una delle funzioni printf,quando ricevi il messaggio dovrai usare printf("%s",buffer);
    se vuoi tornarlo a convertire dovrai prima togliere i caratteri superflui che hai aggiunto e poi usare l'atof.
    Uno invia 8 byte, ma in ricezione gli possono arrivare 8, 4+4, 5+3, o qualunque altra suddivisione l'infrastruttura di rete decida di utilizzare.
    Questo è vero ma a livello piu basso.Il protocollo tcp ci garantisce che il pacchetto arrivi esattamente come è stato spedito.(c'è una nota sulla dimensione ma lasciamo stare)
    Bisognerebbe comunque mettere un controllo che testi che siano stati effettivamente letti tutti i byte.
    
    miavar=citta_cli[codice].lat;
        if ( write(sockfd, &miavar, sizeof(double)) <4)
        {
        perror("write error");
        exit(-1);
        }
    
    
    if (read(connfd, &miavar ,sizeof(double))<4)
        {
            perror("read error");
            exit(-1);
            }
    
    bisognerebbe vedere anche come hai impostato il socket comunque prova il codice cosi e vedi come ricevi.
  • Re: Problema client/server

    Io suggerisco di provare questo codice ...
    
    	int fd = 0;
    	int by, bytot = 0;
    	double ri = 0;
    	
    	while(bytot < sizeof(double))
    	{
    		by = myread(sockfd, (unsigned char *)(&ri)+bytot, sizeof(double)-bytot);
    
    		if(by < 0) 
    		{
            perror("read error");
            exit(-1);
    		}
    
    		if(by == 0)
    		{
    			printf("connection lost\n");
    			break;
    		}
    
    		bytot += by;
    	}
    
            // valore ricevuto in ri
    
    fermo restando che il codice per l'invio deve essere
    
    double va = citta_cli[codice].lat;
    if(write(sockfd, &va, sizeof(double)) <0)
    {
        perror("write error");
        exit(-1);
    }
    
  • Re: Problema client/server

    vbextreme ha scritto:


    Questo è vero ma a livello piu basso.Il protocollo tcp ci garantisce che il pacchetto arrivi esattamente come è stato spedito ...
    Guarda che no!
    Lo so per esperienza diretta!

    La libreria che ho descritto precedentemente l'ho dovuta effettivamente implementare proprio per questo motivo. Poi, c'e' il limite dei 65540 byte (byte piu', byte meno)

    Diciamo che per culo, con pochi byte inviati alla volta e un po' di tempo tra un invio e l'altro, non ci si accorge del problema. Ma se invi alla massima velocita' disponibile sulla rete, ci sbatti immanchevolmente il grugno!
  • Re: Problema client/server

    Il protocollo garantisce l'ordine dei byte non il numero di sequenze necessarie né la loro lunghezza.
  • Re: Problema client/server

    oregon ha scritto:


    Il protocollo garantisce l'ordine dei byte non il numero di sequenze necessarie né la loro lunghezza.
    Questo era sottointeso, se no non si parlava di TCP, ma di qualche altra cosa
  • Re: Problema client/server

    migliorabile ha scritto:


    oregon ha scritto:


    Il protocollo garantisce l'ordine dei byte non il numero di sequenze necessarie né la loro lunghezza.
    Questo era sottointeso, se no non si parlava di TCP, ma di qualche altra cosa
    In un forum non si sottointende nulla ma si scambiano informazioni con chi, più inesperto, non dà nulla per scontato.
  • Re: Problema client/server

    oregon ha scritto:


    In un forum non si sottointende nulla ma si scambiano informazioni con chi, più inesperto, non dà nulla per scontato.
    Se non sottointendi una base minima di conoscenze, la vedo complicata.

    Le informazioni fornite vanno dettagliate in modo intelligente, altrimenti devi fare un trattato per ogni singola risposta.

    Si dettaglieranno via via che ci si accorge che l'interlocutore non capisce.

    Altrimenti, non puoi dare per scontato che il byte sia di 8 bit, che un bit possa valere solo 0/1 , che 0 e 1 siano dei numeri ...
  • Re: Problema client/server

    Qui non parliamo di bit e byte ma di TCP e il livello medio dei partecipanti è lontanissimo dal tuo.

    Quindi non sottointendere nulla.
Devi accedere o registrarti per scrivere nel forum
30 risposte