Pagina 2 di 3 primaprima 1 2 3 ultimoultimo
Visualizzazione dei risultati da 11 a 20 su 23
  1. #11
    Utente di HTML.it
    Registrato dal
    Mar 2012
    Messaggi
    214
    Dunque, i server sono 3, i socket anche, i clienti 7. Ogni cliente si connette a tutte e tre i socket, per un totale di 21 connessioni, 7 per ogni server.

    La stampa è semplicemente il risultato dell'inserimento di queste istruzioni nel codice del client e del server:

    printf("Client: connessione %d\n", connect() );
    printf("Server -accept : %d\n", accept() );

    Ho evitato di mettere i parametri nelle funzioni, servono solo per darti un'idea. Il risultato di connect su una stessa socket è lo stesso per tutti i clienti che ne fanno richiesta, mentre il risultato dell'accept varia...

  2. #12
    Utente di HTML.it
    Registrato dal
    Sep 2012
    Messaggi
    707
    Originariamente inviato da Smoke666
    Il risultato di connect su una stessa socket è lo stesso per tutti i clienti che ne fanno richiesta, mentre il risultato dell'accept varia...
    Sì ma sono processi diversi! Mica è lo stesso socket perché ha lo stesso numero...
    Ogni processo client ha il "suo" socket e non c'è bisogno di semafori.

  3. #13
    Utente di HTML.it
    Registrato dal
    Mar 2012
    Messaggi
    214
    Ma allora perchè senza quel semaforo molte connessioni sono "perse per strada" ? Dove mi consigli di "andarle a cercare"?

    Il server accetta la connessione, crea il thread che fa la lettura. Non è che ci siano grossi passaggi di mezzo...Non capisco proprio dove potrebbe stare il problema se non li...

  4. #14
    Utente di HTML.it
    Registrato dal
    Sep 2012
    Messaggi
    707
    Originariamente inviato da Smoke666
    Ma allora perchè senza quel semaforo molte connessioni sono "perse per strada" ? Dove mi consigli di "andarle a cercare"?
    Come posso sapere io che problemi di connessione hai? Connessione "perdute" o "perse per strada" non è un termine tecnico da cui possa capire cosa succede.

    P.S. Io comunque un dubbio del genere non l'avevo mai visto (cioè pensare che il file descriptor fosse condiviso tra processi visto che aveva lo stesso numero), al riguardo ho trovato questo:
    http://unix.stackexchange.com/questi...-the-same-file

  5. #15
    Utente di HTML.it
    Registrato dal
    Mar 2012
    Messaggi
    214
    So che non è un termine tecnico, ma non riesco a trovarlo neppure io questo termine! La situazione è la seguente:

    - con i semafori che sincronizzano i clienti (che sono sette), ricevo 7 connessioni. Per il momento non faccio niente, le conto e basta. Ne ricevo 7, ovvero il server chiama 7 volte la accept.
    - senza semafori il server chiama un numero variabile di volte la accept, a volte accetta una connessione, a volte un paio, a volte nessuna. Senza un errore, un errno settata da qualche funzione...Niente.

    Il motivo per il quale sono andato a mettere un semaforo sulla connessione dei client è semplice: il server teoricamente fa quello che deve, si blocca sulla accept, quando riceve un segnale chiude il socket e termina. Se utilizzo una comunicazione "sequenziale", ovvero un cliente per volta chiede la connessione, esegue il suo codice, termina e poi avvia l'altro, non ho problemi, funziona egregiamente. Quando più clienti sono avviati contemporaneamente mi ritrovo la situazione descritta sopra...

  6. #16
    Utente di HTML.it
    Registrato dal
    Sep 2012
    Messaggi
    707
    Originariamente inviato da Smoke666
    Il motivo per il quale sono andato a mettere un semaforo sulla connessione dei client è semplice: il server teoricamente fa quello che deve, si blocca sulla accept, quando riceve un segnale chiude il socket e termina.
    Calma. Il motivo per cui ti sei messo a usare i semafori non è solo questo, è addirittura il fatto che pensavi che tutti i client condividessero lo stesso socket in quanto il numero del file descriptor era lo stesso (il 4).

    Ora visto che questo fatto non sussiste, semplifica il tuo codice e studiati solo la fase di connessione al server, avrai certamente sbagliato qualcosa lato server o lato client.

  7. #17
    Utente di HTML.it
    Registrato dal
    Mar 2012
    Messaggi
    214
    Non so se aprire un altro posto o meno, in ogni caso ho seguito il tuo consiglio e sono riuscito a ricavare un errore. Prima di tutto sbagliavo la gestione dei messaggi in arrivo lato server: i client inviano un messaggio e si sospendono in attesa di risposta. Lato server, se il messaggio viene ricevuto male, davo subito un return -1, non riattivando mai il cliente. Ecco che dunque ho individuato lo stallo che mi si creava. Tuttavia ora mi rimane un errore che ricevo quando i messaggi in entrata sono un numero "notevole". Ho fatto la prova con 2 clienti e tutto va a buon fine, quando i clienti sono 3 invece, alcune receive mi restituiscono "Transport endpoint is not connected", dunque alcuni messaggi non vengono ricevuti dal server. Il codice del server è il seguente:

    codice:
    while(1){
    int acp = acceptConnection();  //Funzione di libreria che fa semplicemente una accept
    if( acp != -1){
       pthread_create(&t_id[i], &attr, foo, (void*)&acp); //in attr c'è semplicemente lo stato di joinable, t_id è //un array di pthread_t
    }
    
    void *foo(void *par){
    int sock = *(int*)par; 
    
    pthread_mutex_lock(mutex); 
    int recv = receiveMessage(sock, dest_messaggio); //Fa una receive di un messaggio impacchettato seguendo il //protocollo TLV. 
    if(recv <= 0) perror("Receive"); 
    pthread_mutex_unlock(mutex); 
    }
    La cosa strana ora è solo una: nella funzione receive message io ho impostato in diversi punti la stampa di eventuali errori, ricevendo però sempre e comunque l'esito success... La funzione è piuttosto semplice:

    prende in input il socket descriptor e una struttura dove salvare il messaggio, dopodichè effettua nell'ordine:
    codice:
    int letti = read(socket, msg->type, sizeof(char)); //leggo il tipo
    if(letti <= 0){
    perror("Leggo tipo"); 
    return -1;
    }
    
    letti = read(socket, msg->length, sizeof(int64_t)); //leggo lunghezza buffer
    if(letti <= 0){
    perror("Leggo int"); 
    return -1;
    }
    
    letti = 0;
    while( (letti += read(sc, msg->buffer, msg->length)) < msg->length){ //leggo buff
    if(letti <= 0){
       perror("Leggo buffer"); 
       return -1;
    }
    }
    I vari "perror" interni alla funzione non mi restituiscono errori, tuttavia la chiamata perror("Receive") nel thread talvolta si...Non capisco il perchè...

  8. #18
    Utente di HTML.it
    Registrato dal
    Sep 2012
    Messaggi
    707
    Una cosa che mi salta subito all'occhio, anche se non sarà la causa del problema, ma certe volte da cosa nasce cosa, è quel pthread_mutex_lock/pthread_mutex_unlock con cui "definisci" la regione critica.
    Perché TUTTA quella regione è critica? Dentro receiveMessage c'è una zona critica (accedi in scrittura a una variabile condivisa) ? Se sì, quale? Dovresti circondare con pthread_mutex_lock/pthread_mutex_unlock esclusivamente l'accesso in scrittura a quella variabile condivisa tra thread (se c'è), non tutta la funzione.

    Inoltre la read mi sembra sbagliata, a meno che hai fatto copia/incolla male.
    Anche senza vedere la struttura che usi per msg, vedo che usi msg->length come se fosse un int (quartultima riga), ma quando lo leggi poco prima hai scritto msg->length, invece di &msg->length.
    Anche quando leggi msg->type presuppone che tu l'abbia dichiarato: char type[1].
    È meglio che riporti anche la struttura che usi per msg.

  9. #19
    Utente di HTML.it
    Registrato dal
    Mar 2012
    Messaggi
    214
    Hai ragione, è stato un errore di copia-incolla. La regione critica non è in quel punto, ma poco dopo, quando vado ad aggiungere il messaggio appena letto ad una lista di messaggi comune a tutti i thread. Dunque la mutua esclusione viene acquisita dal thread dopo la lettura corretta del messaggio, che ha la seguente struttura:
    codice:
    typedef struct {
      /** tipo del messaggio */
        char type;           
      /** lunghezza messaggio in byte */
        unsigned int length; 
      /** buffer messaggio */
        char buffer[MAXBUF];        
    } message_t;
    Non posso modificare il codice di sopra, dunque ho commesso un errore di battitura, le read sono in questa forma:

    read(sc, &msg->type, sizeof(char) );
    read(sc, &msg->length, sizeof(int64_t) );
    read(sc, msg->buffer, msg->length))

  10. #20
    Utente di HTML.it
    Registrato dal
    Sep 2012
    Messaggi
    707
    Ci sono sicuramente 2 errori:
    1) la regione critica pthread_mutex_lock/unlock devi metterla solo intorno al punto in cui vai ad aggiungere il messaggio alla lista, altrimenti ogni thread blocca tutti gli altri per tutta la ricezione del messaggio
    2) è sbagliato:
    read(sc, &msg->length, sizeof(int64_t) );
    length è un unsigned int (4 byte) invece tu leggi per 8 byte (sizeof(int64_t))
    O trasformi length in un int64_t oppure invii sulla rete un unsigned int e scrivi:
    read(sc, &msg->length, sizeof(unsigned int) );

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 © 2026 vBulletin Solutions, Inc. All rights reserved.