Salve a tutti ho un problema con un programma client/server scritto in c.
Il client invia al server una stringa con il nome di un file e un intero rappresentante il numero massimo di caratteri che ogni riga del file puo' avere.
Il server legge il nome del file, prova ad aprirlo e se l'operazione riesce, e risponde con le righe di testo del file che hanno un numero di caratteri <= all'intero passato dal client.

Il problema sta nel server quando effettuo la seconda read() da stream socket:
ricevo o l'errore "bad file descriptor" o non riesco a leggere l'intero.

Posto il codice di client e server. Il problema e' commentato.
client.c
codice:
#include <stdio.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <netdb.h>
#include <fcntl.h>
#include <signal.h>
#include <errno.h>

#define DIM_BUFF 256

int main(int argc, char** argv){
	//controllo argomenti e inizializzazione strutture dati
	int sd, fd_file, nread,nwrite,numCar;
	char buff[DIM_BUFF],ok;
	char nome_ric[FILENAME_MAX+1];
	char lungRighe[20];
	struct hostent * host;
	struct sockaddr_in serveraddr;
	
	if(argc!=3){
		printf("Errore invocazione comando client: host porta\n");
		exit(1);
	} 
	//inizializzo indirizzo server
	memset((char*)&serveraddr, 0, sizeof(struct sockaddr_in));
	serveraddr.sin_family = AF_INET;
	host = gethostbyname("localhost");
	if(host == NULL){
		printf("Host not found.\n");exit(2);
	}
	//verifica porta
	serveraddr.sin_addr.s_addr = ((struct in_addr*)(host->h_addr))->s_addr;
	serveraddr.sin_port = htons(atoi("1234"));

	//client
	printf("Client per trasferimento righe file.\n");
	printf("Nome del file da richiedere al server, EOF per terminare:\n");
	while(gets(nome_ric)){
		printf("File da cercare: %s.\n", nome_ric);
		printf("Numero dei caratteri ammessi per le righe da mostrare:\n");
		while(gets(lungRighe)==NULL){
			printf("Numero dei caratteri ammessi per le righe da mostrare:\n");
		}
		printf("Numero caratteri: %s\n", lungRighe);
		sd = socket(AF_INET, SOCK_STREAM, 0); //creo socket
		if(sd<0){
			perror("Errore creazione socket.\n");
			exit(2);
		}
		printf("Socket creata: sd = %d\n", sd);
		if(connect(sd, (struct sockaddr *)&serveraddr, sizeof(struct sockaddr))<0){
			perror("Errore connessione.\n");
			exit(2);
		}
		//invio il nome del file e aspetto risposta
		//invio numero di righe
		
		numCar = atoi(lungRighe);
		numCar = htonl(numCar);
		if((nwrite=write(sd, &nome_ric, sizeof(nome_ric)))<0){
			perror("Errore scrittura...\n");
			close(sd); exit(4);
		}
		if((nwrite=write(sd, &numCar, sizeof(numCar)))<0){//la read sul server di questa non mi funziona
			perror("Errore scrittura...\n");
			close(sd); exit(4);
		}
		printf("Attendo risposta...\n");
		if(read(sd, &ok, 1)<0){
			perror("Errore lettura risposta.\n");
			continue;
		}
		if(ok=='S'){
			//leggo fino a chiusura sd
			while((nread=read(sd, buff, sizeof(buff)))>0){
				if(nwrite = write(1, buff, nread)<0){
					perror("Errore ricezione file.\n");
					break;
				}
			}if(nread<0){
				perror("Errore ricezione file.\n");
				close(sd);
				printf("Nome del file da richiedere: \n");
				continue;
			}
		}
		else if(ok=='N'){
				printf("File inesistente.\n");
			}
			close(sd);
			printf("Nome del file da richiedere: \n");
	}
	printf("Client: Termino...\n");
	exit(0);
}
server.c
codice:
#include <stdio.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <netdb.h>
#include <fcntl.h>
#include <signal.h>
#include <errno.h>
#include <dirent.h>
#include <string.h>
#define max(a,b) ((a) > (b) ? (a) : (b))
#define DIM_BUFF 256


int conta_file(char * nome_dir, int soglia){
	printf("Sono in conta file.\n");
	DIR * dir; 
	struct dirent * dd;
	FILE * curr;
	int count=0,countTot=0;
	char nome_file[20];
	if((dir = opendir(nome_dir))!=NULL){
	while((dd = readdir(dir))!=NULL){
		printf("%s\n",dd->d_name);
		if((strcmp(dd->d_name,".."))==0 || (strcmp(dd->d_name,"."))==0) printf("Salto .. e .\n");
		else{			
			char * res;
			char linea[256];
			printf("Aggiusto nomi dei file.\n");
			strcpy(nome_file, nome_dir);
			strcat(nome_file, "/");
			printf("%s\n", nome_file);
			strcat(nome_file, dd->d_name);
			printf("%s\n", nome_file);
			curr = fopen(nome_file, "r");
			if(curr==NULL) perror("Errore apertura file.\n");
			
			else{
			count = 0;
			while((res = fgets(linea, 256, curr))!=NULL){
					count++;
				}
			}
			fclose(curr);
			printf("%d\n",count);
			if(count<=soglia) countTot++;
		}
		
		
	}
	printf("Numero totale di file(s) con righe sotto la soglia %d contati: %d\n",soglia, countTot);
	}
	
	closedir(dir);
	return countTot;
}


void gestore(int signo){
	int stato;
	printf("esecuzione gestore SIGCHLD\n");
	wait(&stato);
}

int main(int argc, char ** argv){
	int listenfd, connfd, udpfd, nready, maxfdp1, numCar;
	char zero=0, buff[DIM_BUFF], nome_file[20], nome_dir[20], num_car[20];
	const int on = 1;
	fd_set rset;
	FILE * fd_file;
	char * res;
	char buffer[256];
	int len, nread, nwrite, num, ris,port,numCar;
	struct sockaddr_in clientaddr, serveraddr;

	//controllo argomenti...
	memset((char *)&serveraddr, 0, sizeof(serveraddr));
	serveraddr.sin_family=AF_INET;
	serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
	serveraddr.sin_port = htons(1234);

	//tcp in ascolto
	listenfd = socket(AF_INET, SOCK_STREAM, 0);
	if(listenfd<0){
		perror("Errore creazione socket d'ascolto.\n");
		exit(1);
	}
	if(setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on))<0){
		perror("Errore set opt.\n");
		exit(1);
	}
	if(bind(listenfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr))<0){
		perror("Errore bind.\n");
		exit(1);
	}
	if(listen(listenfd, 5)<0){
		perror("Errore creazione coda d'ascolto.\n");
		exit(1);
	}
	
	//socket udp
	udpfd = socket(AF_INET, SOCK_DGRAM, 0);
	if(udpfd<0){
		perror("Errore creazione socket udp.\n");
		exit(2);
	}
	if(setsockopt(udpfd, SOL_SOCKET,SO_REUSEADDR, &on, sizeof(on))<0){
		perror("Errore set opt per udp.\n");
		exit(2);
	}
	if(bind(udpfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr))<0){
		perror("Errore bind udp.\n");
		exit(2);
	}
	//inizio attività server
	signal(SIGCHLD, gestore);
	FD_ZERO(&rset);
	maxfdp1 = max(listenfd, udpfd)+1;
	for(;;){
		FD_SET(listenfd, &rset);
		FD_SET(udpfd, &rset);
		if((nread = select(maxfdp1, &rset, NULL,NULL, NULL))<0){
			if(errno==EINTR) continue;
			else {perror("Errore nella select.\n");exit(3);}
		}
		if(FD_ISSET(udpfd, &rset)){
			
			len = sizeof(struct sockaddr_in);
			if(recvfrom(udpfd, &nome_dir, sizeof(nome_dir), 0, (struct sockaddr *)&clientaddr, &len)<0){
				perror("Errore recvfrom nome udp.\n");
				continue;
			}
			if(recvfrom(udpfd, &num, sizeof(num), 0, (struct sockaddr *)&clientaddr, &len)<0){
				perror("Errore recvfrom num udp.\n");
				continue;
			}	
			printf("Ho ricevuto dal client udp: %s %d\n", nome_dir, ntohl(num));
			num = ntohl(num);
			num = conta_file(nome_dir, num);
			ris = htonl(num);
			if(sendto(udpfd, &ris, sizeof(ris), 0, (struct sockaddr *)&clientaddr, len)<0){
				perror("Errore sendto udp.\n");
				continue;
			}
		}
		if(FD_ISSET(listenfd, &rset))
		{
			len = sizeof(struct sockaddr_in);
			if((connfd = accept(listenfd, (struct sockaddr*)&clientaddr,&len))<0){
				if(errno==EINTR) continue;
				else{ perror("Errore nella accept.\n"); exit(4);}
			}
			if(fork()==0){
				close(listenfd);
				printf("Sono il figlio: %d\n", getpid());
				if((nread=read(connfd, &nome_file, sizeof(nome_file)))<=0){
					perror("Errore lettura fd figlio.\n");
					break;
				}
				
				if((nread=read(connfd, &numCar, sizeof(numCar)))<=0){//questa read o genera Bad File Descriptor o risulta vuota
										//ho provato anche a passare una stringa dal client e nel server a 
										//convertirla con atoi...ma risulta vuota. Se passo un intero, sia con 
										//sizeof(int) o con sizeof(nomeInt) risulta comunque vuota.Dove sbaglio?
					perror("Errore lettura fd figlio.\n");
					break;
				}
				printf("Ho letto: %s\n", nome_file);//qui leggo correttamente nome file
				printf("Ho letto: %d\n", ntohl(numCar));//qui non leggo nulla
				fd_file = fopen(nome_file, O_RDONLY);
				if(fd_file<0){
					write(connfd, "N", 1);
				}
				else{
					write(connfd, "S", 1);
					while((nread=read(fd_file, buff, sizeof(buff)))>0){
						if(nwrite = write(connfd,buff, nread)<0){
							perror("Errore scrittura file.\n");
							break;
						}
					}
					close(fd_file);
				}
				close(connfd);
				exit(0); //solo figlio
			}
			close(connfd);
		}
	}
	printf("Server: Termino...\n");
}
Manca il codice del client udp ma e' irrilevante visto che funziona e non e' fondamentale al funzionamento del programma.
Spero in un aiuto.
Grazie ciao.