codice:
#include "header.h"
int psockfd, csockfd, letti, scritti, num_pack, mod_pack, len, i;
unsigned int paddrlen, caddrlen;
char azione, *ultimo, *ultimo_lista;
char nomefile[MAXLINE + 1], directory[MAXLINE], errore[MAXLINE] = "Il file cercato non esiste.\n", approvato[MAXLINE] = "Il file cercato esiste.\n", lista_file[MAXLINE] = "Lista file server";
DIR *dp;
FILE *filep, *fopen(), *list_fd;
struct sockaddr_in temp;
struct dirent *dir_p;
struct sockaddr_in pclntddrss;
struct sockaddr_in cclntddrss;
struct Pacchetto
{
int num_seq;
char bit_string[MAXLINE];
} inviato;
int main()
{
//Creazione del socket del processo padre
if((psockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
perror("Errore nella creazione del socket.\n");
exit(1);
}
//Azzeramento dello spazio di memoria con l'indirizzo della variabile clntddrss
memset((void *)&pclntddrss, 0, sizeof(pclntddrss));
//Assegnazione del tipo di indirizzo
pclntddrss.sin_family = AF_INET;
//Connessioni accettate su qualunque interfaccia di rete
pclntddrss.sin_addr.s_addr = htonl(INADDR_ANY);
//Assegnazione del numero di porta
pclntddrss.sin_port = htons(SERV_PORT);
//Assegnazione dell'indirizzo al socket
/*nella prima parte struct sockaddr... fino alla virgola, cambia il tipo della variabile clntddrss*/
if ((bind(psockfd, (struct sockaddr *)&pclntddrss, sizeof(pclntddrss))) < 0)
{
perror("Errore in bind.\n");
exit(1);
}
printf("Il padre ha la porta: %d.\n", ntohs(pclntddrss.sin_port));
for ( ; ; )
{
printf("In attesa dell'azione da svolgere...\n");
paddrlen = sizeof(pclntddrss);
//Controllo del tipo di richiesta del client
if((letti = recvfrom(psockfd, &azione, 1, 0, (struct sockaddr *)&pclntddrss, &paddrlen)) < 0)
{
perror("Errore in lettura.\n");
exit(1);
}
printf("L'azione scelta è: %c.\n", azione);
//Creazione socket processo figlio
if((csockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
{
perror("Errore nella creazione del socket.\n");
exit(1);
}
//Azzeramento dello spazio di memoria con l'indirizzo della variabile clntddrss
memset((void *)&cclntddrss, 0, sizeof(cclntddrss));
//Assegnazione del tipo di indirizzo
cclntddrss.sin_family = AF_INET;
//Connessioni accettate su qualunque interfaccia di rete
cclntddrss.sin_addr.s_addr = htonl(INADDR_ANY);
//Assegnazione del numero di porta
cclntddrss.sin_port = htons(0);
//Assegnazione dell'indirizzo al socket
if ((bind(csockfd, (struct sockaddr *)&cclntddrss, sizeof(cclntddrss))) < 0)
{
perror("Errore in bind.\n");
exit(1);
}
unsigned int dim = sizeof(temp);
getsockname(csockfd, (struct sockaddr *)&temp, &dim);
printf("Il figlio ha la porta: %d.\n", ntohs(temp.sin_port));
//Invio numero di porta del socket del processo figlio
if(scritti = sendto(psockfd, (int*)&temp.sin_port, 4, 0, (struct sockaddr *)&pclntddrss, sizeof(pclntddrss)) < 0)
{
perror("Errore in scrittura.\n");
exit(1);
}
//Creazione del processo figlio
pid_t pid = fork();
//Controllo 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());
close(psockfd);
if(azione == 'l' || azione == 'L')
{
printf("L'utente ha richiesto la lista dei file.\n");
//Directory di lavoro del server
getcwd(directory, sizeof(directory));
//Apertura della directory
dp = opendir(directory);
printf("Directory aperta.\n");
if(dp == NULL) exit(1);
printf("Funziona.\n");
dir_p = readdir(dp);
//Apertura del file della lista. Se non esiste viene creato
list_fd = fopen(lista_file, "w+");
//Scrittura nel file
while ((dir_p = readdir(dp)) != NULL)
{
if ((strcmp(dir_p -> d_name, "server.c") && strcmp(dir_p -> d_name, "server") && strcmp(dir_p -> d_name, "header.h")) != 0)
{
fprintf(list_fd, "%s\n", dir_p -> d_name);
}
}
//Controllo della dimensione del file
//Spostamento a fine file
fseek(list_fd, 0L, SEEK_END);
//La ftell ritorna la posizione
len = ftell (list_fd) + 1;
printf("Il file occupa %d Byte.\n", len);
//Spostmento ad inizio file
fseek(list_fd, 0L, SEEK_SET);
fclose(list_fd);
list_fd = fopen(lista_file, "rb");
//Calcolo e trasmissione del numero di pacchetti necessari per l'invio
//Numero di pacchetti in cui verrà diviso il file
num_pack = len / MAXLINE;
//Il resto è la dimensione dell'ultimo pacchetto
mod_pack = len % MAXLINE;
//Arrotondamento del numero di pacchetto all'intero superiore
if (mod_pack > 0)
{
num_pack++;
printf("Il numero di pacchetti da inviare è: %d.\n", num_pack);
printf("La dimensione dell'ultimo pacchetto è: %d.\n", mod_pack);
}
else
{
printf("Il numero di pacchetti da inviare è: %d.\n", num_pack);
mod_pack = MAXLINE;
}
//Stampa di controllo
printf("mod_pack = %d.\n", mod_pack);
//Invio il numero di pacchetti al client
if (scritti = sendto (csockfd, (int*)&num_pack, 4, 0, (struct sockaddr *)&cclntddrss, sizeof(cclntddrss)) < 0)
{
perror("Errore in scrittura.\n");
exit(1);
}
//Invio la dimensione dell'ultimo pacchetto al client
if (scritti = sendto (csockfd, (int*)&mod_pack, 4, 0, (struct sockaddr *)&cclntddrss, sizeof(cclntddrss)) < 0)
{
perror("Errore in scrittura.\n");
exit(1);
}
//Settggio a zero del numero di sequenza
inviato.num_seq = 0;
for (i = 0; i < num_pack - 1; i++)
{
inviato.num_seq ++;
//Leggo dal file la parte che mi interessa
fread(inviato.bit_string, MAXLINE, 1, list_fd);
//Invio della parte del file
if (scritti = sendto (csockfd, (void *)&inviato, sizeof(inviato), 0, (struct sockaddr *)&cclntddrss, sizeof(cclntddrss)) < 0)
{
perror("Errore in scrittura.\n");
exit(1);
}
printf("%d / %d pacchetti inviati | Numero di sequenza del pacchetto: %d.\n", i+1, num_pack, inviato.num_seq); //Una parte della stampa è di controllo
}
ultimo_lista = (char*) malloc (mod_pack);
fread(ultimo_lista, mod_pack, 1, list_fd);
if(scritti = sendto (csockfd, ultimo_lista, mod_pack, 0, (struct sockaddr *)&cclntddrss, sizeof(cclntddrss)) < 0)
{
perror("Errore in scrittura.\n");
exit(1);
}
printf("%d / %d pacchetti inviati | Numero di sequenza del pacchetto: %d.\n", i+1, num_pack, inviato.num_seq + 1); //Una parte della stampa è di controllo
fclose (list_fd);
closedir(dp);
}
//Chiusura socket figlio
close(csockfd);
//Terminazione processo figlio
exit(EXIT_SUCCESS);
}
//Codice processo padre
else
{
//Chiusura socket figlio
close(csockfd);
//Eliminazione degli zombie
waitpid (-1, NULL, WNOHANG);
}
}
exit(0);
}
e l'header: