Visualizzazione dei risultati da 1 a 5 su 5

Discussione: [C] Problemi di Thread

  1. #1
    Utente di HTML.it
    Registrato dal
    May 2004
    Messaggi
    115

    [_C_] Problemi di Thread

    Salve ragazzi,
    devo realizzare una chat e per gestire le connessioni multiple devo utilizzare i thread. Purtroppo sono un novizio dei threads e mi capita che la funzione che dovrebbe svolgere ciascun thread non è realizzata. Vi allego server.c per farvi capire meglio il problema e l'eventuale errore. nOn ho problemi con i clients.
    Ragazzi vi prego aiutatemi.

    #include <sys/types.h>
    #include <sys/socket.h>
    #include <sys/wait.h>
    #include <netinet/in.h>
    #include <fcntl.h>
    #include <stdio.h>
    #include <unistd.h>
    #include <errno.h>
    #include <signal.h>
    #include <pthread.h>
    #define PORTNUM 15000
    #define MAX_NUM_CLIENTS 50

    void fireman()
    {
    union wait wstatus;
    while(wait3(&wstatus,WNOHANG,NULL)>0);
    }

    int crea_socket(int porta)
    {
    int sock_id;
    struct sockaddr_in addr;

    if( (sock_id=socket(AF_INET,SOCK_STREAM,0))<0 )
    {
    perror("Errore nella creazione del socket");
    printf("\n\nTerminazione\n");
    exit(-1);
    }
    memset((void *)&addr,0,sizeof(addr));
    addr.sin_family=AF_INET;
    addr.sin_addr.s_addr=INADDR_ANY;
    addr.sin_port=htons(porta);

    if(bind(sock_id,(struct sockaddr *)&addr,sizeof(addr)))
    {
    perror("Errore di Binding");
    printf("\n\nTerminazione\n");
    exit(-1);
    }

    if(listen(sock_id,MAX_NUM_CLIENTS)<0)
    {
    perror("Errore di listening");
    printf("\n\nTerminazione\n");
    exit(-1);
    }

    return sock_id;
    }

    ssize_t leggi(int desc, void *buf, size_t count)
    {
    size_t nsin;
    ssize_t nread;

    nsin=count;
    while(nsin>0)
    {
    if( (nread=read(desc, buf, nsin))<0 )
    {
    if(errno==EINTR)
    {
    continue;
    }
    else
    {
    return(nread);
    }
    }
    else if (nread==0)
    {
    break;
    }
    nsin=nsin-nread;
    buf=buf+nread;
    }
    return (count-nsin);
    }
    struct thread_data {
    int thread_id;
    int sock_id;
    };

    struct thread_data thread_buf[MAX_NUM_CLIENTS];

    void *servi(void *thread_arg)
    {
    struct thread_data *mydata;
    mydata=(struct thread_data *) thread_arg;
    int thread_id=mydata->thread_id;
    int sock_id=mydata->sock_id;
    int newsock_id;
    int exit_cond=0;
    int letti;
    char buffer[512];
    printf("Sono entrato\n"); //Controllo se servi è eseguita
    if( (newsock_id=accept(sock_id,0,0))<0 )
    {
    perror("Errore nell'accettazione della connessione");
    printf("\n\nTerminazione\n");
    exit(-1);
    }
    while(exit_cond==0)
    {
    if( (letti=read(newsock_id,buffer,sizeof(buffer)))<0 )
    {
    perror("Errore di lettura");
    printf("\n\nTerminazione\n");
    exit(-1);
    }

    if(strcmp(buffer,"quit\n")==0)
    {
    exit_cond=1;
    }
    else printf("%s\n",buffer);
    }
    close(newsock_id);
    return;
    }

    int main(int argc, char *argv[])
    {
    char buffer[512];
    int sock_id, newsock_id;
    int exit_cond=0;
    int exit_while=0;
    int letti;
    int users=1;
    int rc;
    pthread_t threads[MAX_NUM_CLIENTS];
    if(argc!=1)
    {
    printf("Uso corretto: server ");
    printf("\n\nTerminazione\n");
    exit(-1);
    }

    sock_id=crea_socket(PORTNUM);

    signal(SIGCHLD,fireman);

    while(users>0)
    {
    users=0;
    thread_buf[users].thread_id=users;
    thread_buf[users].sock_id=sock_id;
    if( (rc=pthread_create(&threads[users],NULL,servi,(void *) &thread_buf[users]))<0 )
    {
    perror("Errore nella creazione del thread");
    printf("\n\nTerminazione\n");
    exit(-1);
    }
    users--;
    }
    printf("Fine della comunicazione\n");
    exit(0);
    }

  2. #2
    Utente di HTML.it L'avatar di /dev/null
    Registrato dal
    May 2004
    Messaggi
    1,936
    Non ho capito qual'e' il problema
    Ultima modifica ad opera dell'utente /dev/null il 01-01-0001 alle 00:00

  3. #3
    Utente di HTML.it
    Registrato dal
    May 2004
    Messaggi
    115
    In pratica devo implementare una chat.
    Come vedi dal codice del server, c'è una procedura servi che è eseguita da un thread per ogni nuovo client che si connette.
    In servi c'è una accept su cui il server dovrebbe bloccarsi in attesa di connessioni, ma in realtà tutta quella parte di codice sembra essere saltata e il thread passa direttamente alla stampa
    printf("Comunicazione terminata");
    Questo è il mio problema.

  4. #4
    Utente di HTML.it L'avatar di /dev/null
    Registrato dal
    May 2004
    Messaggi
    1,936
    Originariamente inviato da alextg82
    In pratica devo implementare una chat.
    Come vedi dal codice del server, c'è una procedura servi che è eseguita da un thread per ogni nuovo client che si connette.
    In servi c'è una accept su cui il server dovrebbe bloccarsi in attesa di connessioni, ma in realtà tutta quella parte di codice sembra essere saltata e il thread passa direttamente alla stampa
    printf("Comunicazione terminata");
    Questo è il mio problema.
    Prova ad inserire all'interno della funzione eseguita dal thread una funzione di output: appena inizia quella funzione mettici un bel printf("X\n");..
    Cosi' ti accorgi se il thread ci entra o no... Anche se non vedo perche' non dovrebbe entrarci...
    Se ci entra, ma hai dei problemi all'interno di quella funzione mettici degli altri cout, che stampino il valore di "newsock_id" e di "letti", per assicurarti che quelle funzioni ottengano i risultati sperati...

    Facci sapere




    PS: Quando posti del codice, non metterlo così sfuso nel thread, ma mettilo tra i tag [code] e
    codice:
    [/ code]
    in questo modo viene ben allineato e si riesce a capirci qualcosa... Per esempio:
    codice:
    /* ... */
    if ( a == b ) {                        /* se sono uguali */
        printf ( "Uguali" );
    } else {                               /* se sono diversi */
        printf ( "diversi" );
    }
    /* ... */

    Ultima modifica ad opera dell'utente /dev/null il 01-01-0001 alle 00:00

  5. #5
    Utente di HTML.it
    Registrato dal
    May 2004
    Messaggi
    115
    Ragazzi ho modificato il codice con non solo le stampe e sembra che qualcosa sia cambiato
    Ho capito il problema ma non nso proprio come risolverlo, sembra che il thread si rifiuti di modificare una
    varibiale globale che conta gli utenti della chat (=users).
    Vi rimando di seguito i codici di cleint e server, se ci date un'occhiata mi fate un grade piacere.
    Vi ringrazio, site molto gentili.

    codice:
    /* client.c  */
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <netdb.h>
    #include <unistd.h>
    #include <errno.h>
    #include <stdio.h>
    #define PORTNUM 15000
    
    int crea_socket(char *dest, int porta)
    {
     struct sockaddr_in addr;
     struct hostent *h;
     int sock_id;
    
     addr.sin_family=AF_INET;
     addr.sin_port=htons(porta);
     h=gethostbyname(dest);
     if(h==0)
       {
        printf("Connessione IP alfanumerico fallito\n\n");
        printf("Terminazione\n");
        exit(-1);
       }
     bcopy(h->h_addr,&addr.sin_addr,h->h_length);
     
     if( (sock_id=socket(AF_INET,SOCK_STREAM,0))<0 )
         {
          perror("Errore nella creazione del socket");
          printf("\n\nTerminazione\n");
          exit(-1);
         }
    
     if(connect(sock_id,(struct sockaddr *)&addr,sizeof(addr))<0)
        {
         perror("Errore nella connessione");
         printf("\n\nTerminazione\n");
         exit(-1);
        }
    
     return sock_id;
    }
    
    ssize_t invia(int socket,char *mess)
    {
     size_t nsin;
     ssize_t nscritti;
    
     nsin=strlen(mess);
     while(nsin>0)
       {
        if( (nscritti=write(socket,mess,strlen(mess)))<0)
         {
          if (errno==EINTR)
    	      continue;
          else
    	   return(nscritti);
         }
        nsin=nsin-nscritti;
        mess=mess+nscritti;
       }
     return (strlen(mess));
    }
    
    int main(int argc, char *argv[])
    {
     int sock_id;
     char mess[512];
     int exit_cond=0;
     
     if(argc!=2)
        {
         printf("Uso corretto: client nickname");
         printf("\n\nTerminazione\n");
         exit(-1);
        }
    
     if( (sock_id=crea_socket("127.0.0.1",PORTNUM))<0 )
        {
         perror("Errore nella creazione del socket");
         printf("\n\nTerminazione\n");
         exit(-1);
        }
    
     while(exit_cond==0)
       {
        printf("Messaggio da inviare:  ");
        fgets(mess,512,stdin);
        if(strcmp(mess,"quit\n")==0)
    	 exit_cond=1;
        write(sock_id,mess,strlen(mess));
        printf("Messaggio inviato\n");
       }
     printf("Chat terminata per %s\n",argv[1]);
     close(sock_id);
     exit(0);
    }
    
    /* server.c */
    
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <sys/wait.h>
    #include <netinet/in.h>
    #include <fcntl.h>
    #include <stdio.h>
    #include <unistd.h>
    #include <errno.h>
    #include <signal.h>
    #include <pthread.h>
    #include <time.h>
    #define PORTNUM 15000
    #define MAX_NUM_CLIENTS 50
    
    void fireman()
    {
     union wait wstatus;
     while(wait3(&wstatus,WNOHANG,NULL)>0);
    }
    
    int crea_socket(int porta)
    {
     int sock_id;
     struct sockaddr_in addr;
     
     if( (sock_id=socket(AF_INET,SOCK_STREAM,0))<0 )
    	{
    	 perror("Errore nella creazione del socket");
    	 printf("\n\nTerminazione\n");
    	 exit(-1);
    	}
     memset((void *)&addr,0,sizeof(addr));
     addr.sin_family=AF_INET;
     addr.sin_addr.s_addr=INADDR_ANY;
     addr.sin_port=htons(porta);
    
     if(bind(sock_id,(struct sockaddr *)&addr,sizeof(addr)))
        {
         perror("Errore di Binding");
         printf("\n\nTerminazione\n");
         exit(-1);
        }
     
     if(listen(sock_id,MAX_NUM_CLIENTS)<0)
        {
         perror("Errore di listening");
         printf("\n\nTerminazione\n");
         exit(-1);
        }
     
     return sock_id;
    }
    
    ssize_t leggi(int desc, char *buf, size_t count)
    {
     int nletti=0;
     int da_legg=0;
    
     while(nletti < count)
        {
         if( (da_legg=read(desc, buf, count-nletti))<0 )
    	    {
                 nletti=nletti+da_legg;
    	     buf=buf+da_legg;
    	    }
         if(da_legg<0)		 
    	  return(-1);
        }
     return (nletti);
    }
    
    struct thread_data {
    	int thread_id;
    	int sock_id;
    };
    	
    pthread_mutex_t mutexdata;
    struct thread_data thread_buf[MAX_NUM_CLIENTS];
    struct timespec delay;
    int users=0;
    pthread_t threads[MAX_NUM_CLIENTS];
    
    void *servi(void *thread_arg)
    {
     struct thread_data *mydata;
     mydata=(struct thread_data *) thread_arg;
     int thread_id=mydata->thread_id;
     int sock_id=mydata->sock_id;
     int newsock_id;
     int exit_cond=0;
     int letti;
     char buffer[512];
     pthread_mutex_lock(&mutexdata);
     users++;
     pthread_mutex_unlock(&mutexdata);
     printf("Usr=%d\n",users);
     printf("Thread %d: Socket identity: %d\n\n",thread_id,sock_id);
     while(exit_cond==0)
        {
         if( (letti=read(sock_id,buffer,sizeof(buffer)))<0 )
    	     {
    	      perror("Errore di lettura");
                  printf("\n\nTerminazione\n");
                  exit(-1);
    	     }
    
         if(strcmp(buffer,"quit\n")==0)
    	     {
                  printf("quit\n");
    	      exit_cond=1;
    	      printf("%d\n",exit_cond);
                 }
          else  
    	  {
               printf("%s\n",buffer);
    	  }
        }
     printf("Sto uscendo");
     pthread_mutex_lock(&mutexdata);
     printf("Modifico users");
     users--;
     pthread_mutex_unlock(&mutexdata);
     printf("exit");
     pthread_exit(NULL);
     close(newsock_id);
     return;
    }
     
    int main(int argc, char *argv[])
    {
     char buffer[512];
     int sock_id, newsock_id;
     int exit_cond=0;
     int exit_while=0;
     int letti;
     int rc;
     int status;
     int inizio=0;
     delay.tv_sec=2;
     delay.tv_nsec=0;
     if(argc!=1)
         {
          printf("Uso corretto: server ");
          printf("\n\nTerminazione\n");
          exit(-1);
         }
    
     sock_id=crea_socket(PORTNUM);
    
     signal(SIGCHLD,fireman);
     while((inizio==0) || (users>0 && users<(MAX_NUM_CLIENTS+1)))
        {
         inizio=1;
         printf("Users=%d\n",users);
         if( (newsock_id=accept(sock_id,0,0))<0 )
    	   {
    	    perror("Errore nell'accettazione della connessione");
                printf("\n\nTerminazione\n");
                exit(-1); 
    	   }
         thread_buf[users].thread_id=users;
         thread_buf[users].sock_id=newsock_id;
         if( (rc=pthread_create(&threads[users],NULL,servi,(void *) &thread_buf[users]))<0 )
             {
              perror("Errore nella creazione del thread");
    	  printf("\n\nTerminazione\n");
    	  exit(-1);
    	 }
        }
     pthread_mutex_destroy(&mutexdata);
     printf("Fine della comunicazione\n");
     exit(0);
    }

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