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);
}