ecco il server:
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:
codice:
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <errno.h>
#include <malloc.h>
#include <signal.h>
#include <dirent.h>

#define SERV_PORT   3547
#define BACKLOG       10
#define MAXLINE     1024