codice:
#include "header.h"
int psockfd, csockfd, scritti, letti, num_pack, mod_pack, i;
unsigned int paddrlen, caddrlen;
char azione, *ultimo, *ultimo_lista;
char nomefile[MAXLINE], recvline[MAXLINE + 1], list_file[MAXLINE] = "Lista file server";
int ricporta;
struct sockaddr_in psrvrddrss;
struct sockaddr_in csrvrddrss;
struct Pacchetto
{
int num_seq;
char bit_string[MAXLINE];
} ricevuto;
DIR *dp;
FILE *filep, *fopen(), *list_fd;
int main (int argc, char** argv)
{
//Controllo numero argomenti
if (argc != 2)
{
perror("Indirizzo del server ip mancante.\n");
exit(1);
}
//Creazione del socket del processo padre
if ((psockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
perror("Errore nella creazione del socket.\n");
exit(1);
}
paddrlen = sizeof(psrvrddrss);
//Svuotamento srvraddrss
memset((void *)&psrvrddrss, 0, sizeof(psrvrddrss));
//Assegnazione del tipo di indirizzo
psrvrddrss.sin_family = AF_INET;
//Assegnazione porta del servar
psrvrddrss.sin_port = htons (SERV_PORT);
/*Assegnazione dell'indirizzo del server tramite riga di comando
l'indirizzo è una stringa e va convertito in network byte order*/
if (inet_pton(AF_INET, argv[1], &psrvrddrss.sin_addr) <= 0)
{
fprintf(stderr, "Errore in inet_pton per %s.\n", argv[1]);
exit(1);
}
for ( ; ; )
{
//Menu di scelta azione
printf("Digitare l per ottenere una lista dei file disponibili,\n");
scanf("%c", &azione);
getchar();
//Trasmissione al server l'azione scelta dall'utente
if ((scritti = sendto(psockfd, &azione, 1, 0, (struct sockaddr *)&psrvrddrss, sizeof(psrvrddrss))) < 0)
{
perror("Errore nella scrittura.\n");
exit(1);
}
//Ricezione numero di porta del server
if(letti = recvfrom(psockfd, (int*)&ricporta, 4, 0, (struct sockaddr *)&psrvrddrss, &paddrlen) < 0)
{
perror("Errore in lettura. \n");
exit(1);
}
//Creazione del socket del processo figlio
if ((csockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
perror("Errore nella creazione del socket.\n");
exit(1);
}
caddrlen = sizeof(csrvrddrss);
//Svuotamento srvraddrss
memset((void *)&csrvrddrss, 0, sizeof(csrvrddrss));
//Assegnazione del tipo di indirizzo
csrvrddrss.sin_family = AF_INET;
//Assegnazione porta del servar
csrvrddrss.sin_port = ricporta;
/*Assegnazione dell'indirizzo del server tramite riga di comando
l'indirizzo è una stringa e va convertito in network byte order*/
if (inet_pton(AF_INET, argv[1], &csrvrddrss.sin_addr) <= 0)
{
fprintf(stderr, "Errore in inet_pton per %s.\n", argv[1]);
exit(1);
}
//Creazione processo figlio
pid_t pid = fork();
//Controllo di errore pid
if(pid < 0) printf("Errore nella creazione del processo figlio.\n");
//Codice processo figlio
if(pid == 0)
{
printf("Creato il figlio: %d.\n", getpid());
//Chiusura socket del padre
close(psockfd);
//Menu di scelta
switch (azione)
{
//Lista file
case 'l': case 'L':
printf("Richiedo la lista dei file disponibili...\n");
//Apertura del file in scrittura, binario, se il file non esiste viene creato
list_fd = fopen(list_file, "w+b");
/*Ricezione del numero di pacchetti da ricevere dal server*/
if(letti = recvfrom(csockfd, (int*)&num_pack, 4, 0, (struct sockaddr*)&csrvrddrss, &caddrlen) < 0)
{
perror("Errore in lettura.\n");
exit(1);
}
//Ricezione delle dimensioni dell'ultimo pacchetto
if(letti = recvfrom(csockfd, (int*)&mod_pack, 4, 0, (struct sockaddr*)&csrvrddrss, &caddrlen) < 0)
{
perror("Errore in lettura.\n");
exit(1);
}
if(mod_pack > 0)
{
//Stampe di controllo
printf("Il numero di pacchetti da ricevere è: %d.\n", num_pack);
printf("La dimensione dell'ultimo pacchetto è: %d.\n", mod_pack);
}
else
{
printf("Il numero di pacchetti da ricevere è: %d.\n", num_pack);
mod_pack = MAXLINE;
}
//Azzeramento della memoria contenente i campi della struttura
memset((void *)&ricevuto, 0, sizeof(ricevuto));
//Ricezione pacchetti e copia nel file, tranne l'ultimo
for (i=0; i < num_pack - 1; i++)
{
printf("Sono entrato nel ciclo.\n");
if (letti = recvfrom(csockfd, (void *)&ricevuto, sizeof(ricevuto), 0, (struct sockaddr *)&csrvrddrss, &caddrlen) != sizeof(ricevuto))
{
perror("Errore in lettura.\n");
exit(1);
}
printf("Ho ricevuto il pacchetto.\n");
//Scrittura del pacchetto nel file
fwrite(ricevuto.bit_string, (MAXLINE*sizeof(char)), 1, list_fd);
printf(" %d / %d pacchetti ricevuti | Numero di sequenza pacchetto: %d.\n", i+1, num_pack, ricevuto.num_seq); //Una parte della stampa è di controllo
//Pulitura dei buffer input
fflush(stdin);
}
printf("Dopo il ciclo.\n");
//Allocazione di memoria per l'ultimo pacchetto
ultimo_lista = (char*) malloc(mod_pack);
//Ricezione dell'ultimo pacchetto
if(letti = recvfrom(csockfd, ultimo_lista, mod_pack, 0, (struct sockaddr*)&csrvrddrss, &caddrlen) < 0)
{
perror("Errore in lettura.\n");
exit(1);
}
fwrite(ultimo_lista, (mod_pack), 1, list_fd);
printf(" %d / %d pacchetti ricevuti. Numero di sequenza: %d.\n", i+1, num_pack, ricevuto.num_seq + 1);
fclose(list_fd);
printf("Lista ricevuta con successo.\n");
fflush(stdout);
break;
//Exit
case 'e' : case 'E':
printf("Chiusura programma.\n");
break;
default:
printf("Il comando digitato è errato.\n");
}
close(csockfd);
exit(EXIT_SUCCESS);
}
//Codice processo padre
else
{
//Chiusura socket del figlio
close(csockfd);
//Eliminazione degli zombie
waitpid(-1, NULL, WNOHANG);
//Caso EXIT
if(azione == 'e' || azione == 'E') return(0);
}
}
exit(0);
}