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.