Visualizzazione dei risultati da 1 a 2 su 2
  1. #1

    problema client server in C su invio file!

    ciao a tutti...
    ho un problema con un progetto che sto svolgendo in ambiente linux!
    il progetto è costituito da un client ed un server. Il client visualizza una lista di file da scaricare (streaming.txt) che è stata inviata dal server. La lista è composta da file scritti per riga, esempio:
    [1]primo file
    [2]secondo file
    [3]terzo file
    etc
    il client sceglie la riga e il server passa il file riguardante quella riga, ed è qui che ho un problema perchè sul server esce scritto "open no such file or directory"...
    il programma continua facendo inserire al client una pausa del download, una terminazione forzata senza scaricare nient'altro e una ripresa del download...sicuramente avrò fatto miliardi e miliardi di errori!!
    vi posto il codice del server!
    codice:
    --------SERVER-----
    #include <sys/types.h> /* predefined types */
    #include <unistd.h> /* include unix standard library */
    #include <arpa/inet.h> /* IP addresses conversion utililites */
    #include <sys/socket.h> /* socket library */
    #include <stdio.h> /* include standard I/O library */
    #include <stdlib.h>
    #include <string.h>
    #include <time.h>
    #include <netdb.h>
    #include <fcntl.h>/*gestione file*/
    
    #define BUFSIZE 1024
    #define max(a,b) ((a) > (b) ? (a) : (b))
    
    int visualizza_lista_e_scegli(int conn_fd);
    void file_scelto(int conn_fd,int scelta,char *nomefilescelto);
    
    int main (int argc , char *argv[])
    {
     int list_fd,conn_fd;
     int i,scelta;
     int fd,nread,maxfd,nwrite,k,size,milisec;
     struct sockaddr_in serv_add,client;
     char buffer[BUFSIZE],PRONTO[2],nomefilescelto[256];
     socklen_t len;
     time_t timeval;
     pid_t pid;
     int logging =1;
     struct hostent *rdata;
     fd_set rset,wset;
     milisec = 10; // Dimensione in millisecondi dello sleep
     struct timespec req = {0};
    
     req.tv_sec = 0;
     req.tv_nsec = milisec * 1000000L;
     // Variabile per contare i byte inviati
     size=0;
     // Variabile per la gestione di pausa, ripresa e terminazione del client
     // Se k=0 --> invio normale
     // Se k=1 --> il client ha deciso di mettere in pausa il download
     k=0;
    
     //SOCKET
     if ( ( list_fd = socket(AF_INET, SOCK_STREAM, 0) ) < 0 )
    	{
     perror("socket");
     exit(1);
    	}
    
     //SIN_FAMILY
     serv_add.sin_family = AF_INET;
     //SIN_ADDR.S_ADDR
     serv_add.sin_addr.s_addr = htonl(INADDR_ANY);
     //SIN_PORT
     serv_add.sin_port = htons(1121);
    
     //BIND
     if ( bind(list_fd, (struct sockaddr *) &serv_add,sizeof(serv_add)) < 0 )
    	{
      perror("bind");
      exit(1);
    	}
    
     //LISTEN
     if ( listen(list_fd, 1024) < 0 )
    	{
      perror("listen");
      exit(1);
    	}
    
     /* write daytime to client */
     while(1)
    	{
    	 len = sizeof ( client );
    
    	  if ( ( conn_fd = accept(list_fd, (struct sockaddr *) &client, &len) ) < 0 )
    		{
      	perror("accept");
     	exit(1);
    		}
    
    	 /* fork per gestire il collegamento */
    	 if((pid= fork())<0)
    		{
    		 perror (" fork error ");
    		 exit ( -1);
    		}
    
    	 if(pid==0)
    		{ /* figlio*/
    		 timeval = time ( NULL );
    		 /*Menu di Benvenuto*/
    		 snprintf(buffer,sizeof(buffer)," %.24s\r\n-------------------------------\nWelcome to streaming service, scegliere file desiderato.\nPer terminare premere il numero intero '0'.\nATTENZIONE:un carattere qualsiasi o un numero piu grande terminerà il servizio!\n-------------------------------\n",ctime(& timeval));
    		 if((write(conn_fd,buffer,strlen(buffer)))<0)
    			{
    			 perror (" write error ");
    			 exit ( -1);
    			}
    
     		 if(logging)
    			{
    			 rdata=gethostbyaddr((const char *)&client.sin_addr,sizeof(client.sin_addr),client.sin_family);
    			 if (rdata == NULL)
    				{
    				herror("Errore di risoluzione");
    				exit(1);
    			 	}
    			 printf("\n@Request from host %s, port %d\n%.24s\r\n",rdata->h_name,serv_add.sin_port,ctime(& timeval));
                }
            scelta=visualizza_lista_e_scegli(conn_fd);
            if (scelta==0){
                printf("\nIl tasto scelto ha terminato il servizio streaming.\n\n-------------------------------\n");
                sleep(2);
                close(conn_fd);
                exit(0);
                }
        memset(buffer,0,BUFSIZE);
        file_scelto(conn_fd,scelta,buffer);
        printf("invio file...\n");
        fd = open(buffer,  O_RDONLY);//Apro il file in lettura
        if (fd < 0) {
    		perror(" open error ");
    		exit(1);
    	}
             FD_ZERO(&rset);
             FD_ZERO(&wset);
             maxfd=max(conn_fd, list_fd)+1;
             while(1){
    			/* Se k=0 allora possiamo settare il descrittore del socket
    			   in quanto non ci sono interruzioni da parte del client
    			   e il trasferimento avviene normalmente */
                if(k==0)
                   FD_SET(list_fd,&wset);
                   FD_SET(conn_fd,&rset);
                if (select(maxfd, &rset, &wset, NULL, NULL)<0){
                   perror(" select error ");
                   exit(1);
                }
                /* Usciti dalla select controlliamo se ci sono messaggi per la pausa,
    			   ripresa o terminazione sul socket */
                if(FD_ISSET(conn_fd,&rset)){
                   memset (buffer, 0, sizeof(buffer));
                   if (read(conn_fd, buffer, BUFSIZE)<0)
                      {
    			 perror (" read error ");
    			 exit (-1);
    			}
    			   /* Dal socket leggiamo una 'P' che sta ad indicare una pausa da parte
    				  del client. Quindi 'puliamo' il descrittore del socket, settiamo k=1
    			      e in tal modo mettiamo in pausa il trasferimento dati */
                   if(buffer[0]=='P'){
                      FD_CLR(conn_fd,&wset);
                      k=1;
                      printf("\nCLIENT on PORT %d ha messo in PAUSA il download.",serv_add.sin_port);
                   }
    			   /* Dal socket leggiamo una 'R' che sta ad indicare la volonta'
    			      del client di riprendere il download. Quindi settiamo k=0 per
    			      'riattivare' il descrittore del socket e riprendiamo il trasferimento */
                   if(buffer[0]=='R'){
                      k=0;
                      printf("\n\nCLIENT on PORT %d ha RIPRESO il download.",serv_add.sin_port);
                      printf("\nDownloading...\n");
                   }
    			   /* Dal socket leggiamo una 'S'. Il client vuole terminare senza aver completato il
    			      download. Quindi chiudiamo la connessione ed usciamo dal server figlio
                      che gestiva il client */
                   if(buffer[0]=='S'){
                      printf("\n\nCLIENT on PORT %d ha TERMINATO FORZATAMENTE il download.",serv_add.sin_port);
                      printf("\nConnessione con CLIENT chiusa.\n\n");
                      sleep(2);
    				  close(conn_fd);
                      exit(0);
                   }
                   fflush(stdout);
                }
                /*  Controlliamo se ci sono ancora dati da scrivere sul socket */
                if(FD_ISSET(list_fd,&wset)){
    			   // 'Addormentiamo' il processo per pochi millisecondi
                   nanosleep(&req, (struct timespec *)NULL);
    			   /* Controlliamo se dal file aperto in lettura ci sono ancora da leggere dei byte*/
                   if((nread=read(fd,buffer,1024))<0)
                      {
    			 perror (" read error ");
    			 exit (-1);
    			}
    			   /* Li spediamo */
                   if ((nwrite=sendto(conn_fd, buffer, nread, 0, (struct sockaddr *)&serv_add, len))<0){
                      perror(" sendto error");
                      exit(-1);
                   }
                   size+=nwrite;
    			   /* Se non ci sono piu' byte da leggere dal file allora significa
    			      che il trasferimento e' andato a buon fine. Quindi chiudiamo il
    			      socket ed usciamo dal server figlio.*/
                   if(nread==0){
                      printf("\n\nFile inviato correttamente : \n%d byte al CLIENT on PORT %d.\n\n",size,serv_add.sin_port);
                      close(conn_fd);
                      exit(0);
                     }
                  }
               }//While
            }//pid
            else
    		{ /* padre */
    		 close (conn_fd);
    		}
    	}
     /* normal exit , never reached */
     exit (0);
    }
    
    int visualizza_lista_e_scegli(int conn_fd)
    {
        int scelta, fileDim = 0;
        char *buffer;
      	FILE *file;
    	char ch, FileName[256]="streaming.txt";
    	if(( file = fopen( FileName, "r")) != NULL)
    	{
    		// Si posiziona alla fine del file
    		fseek(file, 0, SEEK_END);
    		// Legge la posizione attuale
    		fileDim = ftell(file);
    		// Alloca la dimensione del buffer
    		buffer = (char*) malloc(sizeof(char) * fileDim+1);
    		printf("\nDimensione del file %s = %d\n", FileName, fileDim);
    		// Mi riporto all'inizio del file
    		fseek(file, 0, SEEK_SET);
    		// Copio tutto il contenuto del file nel buffer
    		fread(buffer, fileDim, 1, file);
    		// Chiudo il file
    		fclose(file);
    	}
    	//inviamo l'elenco al client
    	if(write(conn_fd,buffer,strlen(buffer)+1)<0)
    	{
    			 perror (" write error ");
    			 exit ( -1);
    			}
    	/*leggiamo la scelta del client*/
    	if(read(conn_fd,&scelta,sizeof(scelta))<0)
    	{
    			 perror (" read error ");
    			 exit ( -1);
    			}
    	return (scelta);
    }
    
    void file_scelto(int conn_fd, int scelta, char *buffer)
    {
        FILE *file;
        char FileName[256]="streaming.txt";
        char a[256];
        int i=0;
        if(( file = fopen( FileName, "r")) != NULL)
    	{
    	    //finchè non è finito il file
    	    while(!feof(file))
    	    {
    	        //incrementiamo "i" in modo tale da far combaciare l'array che parte da zero con la lista che parte da uno
                i++;
    	        //leggiamo streaming.txt per righe e lo inseriamo nell'array di stringhe
    	        fgets(a,256,file);
                //quando arriviamo alla scelta del client stampiamo il nome del file desiderato dal client
                if(i==scelta)
                {
                    strcpy(buffer,a);
                    printf("\nè stato scelto il seguente file:\n%s",buffer);
                    //inviamo il nome del file scelto
                    if(write(conn_fd,buffer,BUFSIZE)<0)
                    {
                        perror (" write error ");
                        exit ( -1);
                        }
                    }
                }
            //se la scelta del client è superiore alla lunghezza per righe della lista mandiamo un messaggio d'errore e chiudiamo la connessione
            if ((scelta)>i){
                snprintf(buffer,sizeof(buffer),"ERRORE: il numero premuto è troppo grande per la scelta!\n\nIl tasto scelto ha terminato il servizio streaming.\n\n-------------------------------\n");
                if (write(conn_fd,buffer,strlen(buffer))<0)
                {
                        perror (" write error ");
                        exit ( -1);
                        }
                printf("ERRORE: il numero premuto è troppo grande per la scelta!\n\nIl tasto scelto ha terminato il servizio streaming.\n\n-------------------------------");
                sleep(2);
                close(conn_fd);
                exit(0);
                }
            }
    fclose(file);
    }

  2. #2
    questo invece il client....nn pensavo fossero così lunghi!

    codice:
    --------CLIENT-------
    
    
    #include <netdb.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <arpa/inet.h>
    #include <string.h>
    #include <fcntl.h>
    
    #define BUFSIZE 1024
    #define max(a,b) ((a) > (b) ? (a) : (b))
    
    int scelta_file(int sock);
    void sceltaFileStreaming(int sock, char *buffer);
    
    int main(int argc, char **argv)
    {
      int scelta, sock, n;
      char recvline[1025];
      struct sockaddr_in serv_add;
      char **alias;
      char *addr;
      struct hostent *data;
      char buffer[BUFSIZE],PRONTO[2];
      int fd,k,size,nread,maxfd,addrlen;
      fd_set fset;
    
       // Variabile per contare i byte inviati
       size=0;
       // Variabile per la gestione di pausa, ripresa e terminazione del client
       // Se k=0 --> ricevo normalmente il file
       // Se k=1 --> il client ha deciso di mettere in pausa il download
       k=0;
    
      if (argc != 2)
    	{
        fprintf(stderr,"usage: %s <IPaddress>\n",argv[0]);
        exit (1);
    	}
    
      //SOCKET
      if ( (sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    	{
      fprintf(stderr,"socket error\n");
      exit (1);
    	}
      //SIN_FAMILY
      serv_add.sin_family = AF_INET;
      //SIN_PORT
      serv_add.sin_port = htons(1121);
    
      data = gethostbyname(argv[1]);
    
    	if (data == NULL) {
    		herror("Errore di risoluzione");
    		exit(1);
        }
    
    	alias = data->h_addr_list;
        addr = (char *)inet_ntop(data->h_addrtype, *alias, buffer, sizeof(buffer));
    
    	if (inet_pton(AF_INET, addr, &serv_add.sin_addr) < 0) {
          fprintf(stderr,"inet_pton error for %s\n", argv[1]);
          exit (1);
        }
    
      //CONNECT
      if (connect(sock, (struct sockaddr *) &serv_add, sizeof(serv_add)) < 0) {
        fprintf(stderr,"connect error\n");
        exit(1);
      }
    
      //WHILE READ
      while ( (n = read(sock, recvline, 1024)) > 0) {
        recvline[n] = 0;
        if (fputs(recvline, stdout) == EOF) {
          fprintf(stderr,"fputs error\n");
          exit(1);
        }
    
      if (n < 0) {
        fprintf(stderr,"read error\n");
        exit(1);
      }
        scelta=scelta_file(sock);
        if (scelta==0){
            printf("\nIl tasto scelto ha terminato il servizio streaming.\n\n-------------------------------\nLoading...\n");
            sleep(2);
            close(sock);
            exit(0);
        }
        else
        memset(buffer, 0, BUFSIZE);//puliamo il buffer
        sceltaFileStreaming(sock,buffer);
        if (read(sock,buffer,strlen(buffer))<0)
                {
                        perror (" read error ");
                        exit ( -1);
                        }
        fd = open(buffer, O_CREAT | O_WRONLY,0700);
        memset(buffer,0,BUFSIZE);
    	if (fd < 0)
    		{
    		perror(" open error");
    		exit(1);
    		}
       FD_ZERO(&fset);
       while(1){
          /* Se k=0 allora possiamo settare il descrittore del socket
    		 in quanto non ci sono interruzioni del client
    		 e il download avviene normalmente */
    	  if(k==0)
             FD_SET(sock,&fset);
    	  /* Setto il descrittore dello standard input per controllare
    	     se ci sono tasti digitati da tastiera durante il download */
          FD_SET(fileno(stdin),&fset);
          maxfd=max(sock,fileno(stdin))+1;
          select(maxfd,&fset, NULL, NULL, NULL);
          /* Usciti dalla select controlliamo se e' stato digitato qualche tasto
             e controlliamo l'azione da intraprendere */
    	  if(FD_ISSET(fileno(stdin),&fset)){
             fgets(buffer, BUFSIZE, stdin);
    		 /* E' stata digitata una 'P' che sta ad indicare il mettere in pausa
    		    il download. Quindi 'puliamo' il descrittore del socket, settiamo k=1
    			e in tal modo mettiamo in pausa il trasferimento dati ed inviamo al server
    		    la P inserita sul socket */
             if(buffer[0]=='P'){
                FD_CLR(sock,&fset);
                k=1;
    	        fflush(stdin);
                printf("\nHai interrotto il dowload. Ricevuti : %d byte. \nPremere 'R' per riprendere, 'S' per uscire.\n\n",size);
                if(write(sock, buffer, strlen(buffer))<0)
                   {
    			 perror (" write error ");
    			 exit ( -1);
    			}
             }
    		 /* E' stata digitata una 'R' che sta ad indicare la volonta'
    			di riprendere il download. Quindi settiamo k=0 per
    			'riattivare' il descrittore del socket e riprendiamo il trasferimento.
                Comunichiamo la R al server sul socket */
             if(buffer[0]=='R'){
                k=0;
                printf("\nRiprendo il download... \nPremere 'P' per mettere in pausa, 'S' per uscire.\n\n");
                if(write(sock, buffer, sizeof(buffer))<0)
                   {
    			 perror (" write error ");
    			 exit ( -1);
    			}
             }
    		 /* E' stata digitata una 'S'. Si vuole terminare senza aver completato il
    			download. Quindi inviamo la S tramite socket al server, chiudiamo
                la connessione ed usciamo dal client */
             if(buffer[0]=='S'){
                printf("\nTermine forzato del download... \nConnessione chiusa.\n\n");
                if(write(sock, buffer, strlen(buffer))<0)
                   {
    			 perror (" write error ");
    			 exit ( -1);
    			}
                sleep(2);
                close(sock);
                exit(0);
             }
             memset (buffer, 0, BUFSIZE);
          }
          }
        /*  Controlliamo se ci sono ancora dati da leggere sul socket */
          if(FD_ISSET(sock,&fset)){
             nread=recvfrom(sock, buffer, BUFSIZE, 0, (struct sockaddr *)&serv_add, &addrlen);
             size+=nread;
             if(nread<0){
                perror("recvfrom error");
                exit(1);
             }
             /* Se non ci sono più dati allora il download e' andato a buon fine.
    		    Quindi chiudiamo la connessione ed usciamo dal client */
    		 if(nread==0){
                printf("\nDownload Completato.\nRicevuti %d byte.\n\n",size);
                close(sock);
                exit(0);
             }
    		 /* Se il download non e' completato scriviamo i byte letti sul file aperto
    		    in scrittura */
             if(write(fd,buffer,BUFSIZE)<0)
               {
    			 perror (" write error ");
    			 exit ( -1);
    			}
          }
        exit(0);
     }
    }
    
    int scelta_file (int sock)
    {
        char buffer[1024];
        int scelta;
    	memset(buffer, 0, sizeof(buffer)); /*puliamo il buffer*/
    	/*leggiamo e stampiamo il buffer per la scelta*/
    	if(read(sock,buffer,sizeof(buffer))<0)//legge lista
    	{
    			 perror (" read error ");
    			 exit ( -1);
    			}
    	printf("%s\n",buffer);
    	/*alla richiesta del server digitiamo la nostra scelta
    	e la inviamo al server*/
    	scanf("%d",&scelta);
    	if(write(sock,&scelta,sizeof(scelta))<0) //invia scelta al server
    	{
    			 perror (" write error ");
    			 exit ( -1);
    			}
    	return scelta;
    }
    void sceltaFileStreaming(int sock,char *buffer)
    {
    	if(read(sock,buffer,BUFSIZE)<0) //leggiamo dal server il file scelto
    	{
    			 perror (" read error ");
    			 exit ( -1);
    			}
    	printf("Hai scelto di scaricare:\n%s \nLoading...\n",buffer);//stampa messaggio
    	if (strlen(buffer)>70)
    	{
    	sleep(2);
    	close(sock);
    	exit(0);
    	}
    	sleep(1);
    	printf("\nPremere 'P' per la pausa, 'S' per uscire.\n\n");
    	printf("Download in corso...\n");
    }

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.