25/06/12 17:17
polslinux
Codice del client:
e codice del server:
Come funziona questo programma?
1) client manda nome file al server
2) server manda grandezza file al client
3) server manda il file
4) il client riceve il file
Qual è il problema?
Per esempio sto cercando di copiare un file "prova.txt" grande 2143 bytes, il client riceve la grandezza (2143) e quindi inzia a ricevere il file solo che il client "si blocca" in modalità ricezione e consuma MOLTA cpu!
Inoltre file ricevuto ha una grandezza di 95 byte
Perchè accade ciò?
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <sys/types.h> #include <netdb.h> #include <fcntl.h> #include <stdint.h> #include <inttypes.h> int main(int argc, char *argv[]){ /* Controllo che vi sia argv[0], argv[1] e argv[2] */ if(argc != 4){ printf("Uso: ./client <hostname> <numero porta> <nomefile>\n"); exit(1); } int DescrittoreClient, fd; /* descrittore del socket */ int NumPorta = atoi(argv[2]); /* numero di porta */ struct sockaddr_in serv_addr; /* indirizzo del server */ char nread=0, Buffer[1024] = {}; /* contiene i dati di invio e ricezione */ struct hostent *hp; /* con la struttura hostent definisco l'hostname del server */ char *filename = argv[3]; size_t fsize; int tmp=0, bytes_read; hp = gethostbyname(argv[1]); bzero((char *) &serv_addr, sizeof(serv_addr)); /* bzero scrive dei null bytes dove specificato per la lunghezza specificata */ serv_addr.sin_family = AF_INET; /* la famiglia dei protocolli */ serv_addr.sin_port = htons(NumPorta); /* la porta */ serv_addr.sin_addr.s_addr = ((struct in_addr*)(hp->h_addr)) -> s_addr; /* memorizzo il tutto nella struttura serv_addr */ DescrittoreClient = socket(AF_INET, SOCK_STREAM, 0); if(DescrittoreClient < 0){ perror("Errore nella creazione della socket"); exit(1); } connect(DescrittoreClient, (struct sockaddr *) &serv_addr, sizeof(serv_addr)); if(connect < 0){ perror("Errore nella connessione"); close(DescrittoreClient); exit(1); } strcpy(Buffer, filename); send(DescrittoreClient, Buffer, strlen(Buffer), 0); bytes_read = read(DescrittoreClient, &fsize, sizeof(fsize)); if(bytes_read == -1){ printf("Errore durante ricezione grandezza file\n"); close(DescrittoreClient); exit(1); } fd = open(filename, O_CREAT | O_WRONLY,0644); if (fd < 0) { perror("open"); exit(1); } while(nread != bytes_read){ while ((nread = read(DescrittoreClient, Buffer, sizeof(Buffer))) > 0){ write(fd, Buffer, nread); tmp+=nread; } } printf("File ricevuto\n"); close(DescrittoreClient); return EXIT_SUCCESS; }
e codice del server:
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <sys/types.h> #include <netdb.h> #include <errno.h> #include <fcntl.h> #include <sys/sendfile.h> #include <sys/stat.h> int main(int argc, char *argv[]){ if(argc != 2){ printf("Uso: ./server <numero porta>\n"); exit(1); } int DescrittoreServer, DescrittoreClient, LunghezzaClient; int NumPorta = atoi(argv[1]); struct sockaddr_in serv_addr, cli_addr; /* indirizzo del server e del client */ char Buffer[1024] = {}; int rc, fd, bytes_sent; off_t offset = 0; struct stat stat_buf; char filename[1024] = {}; size_t fsize; DescrittoreServer = socket(AF_INET, SOCK_STREAM, 0); if(DescrittoreServer < 0){ perror("Errore creazione socket\n"); exit(1); } bzero((char *) &serv_addr, sizeof(serv_addr)); /* bzero scrive dei null bytes dove specificato per la lunghezza specificata */ serv_addr.sin_family = AF_INET; /* la famiglia dei protocolli */ serv_addr.sin_port = htons(NumPorta); /* porta htons converte nell'ordine dei byte di rete */ serv_addr.sin_addr.s_addr = INADDR_ANY; /* dato che è un server bisogna associargli l'indirizzo della macchina su cui sta girando */ /* int bind(int descrittore_socket, struct sockaddr* indirizzo, int lunghezza_record_indirizzo) */ if(bind(DescrittoreServer, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0){ perror("Errore di bind\n"); close(DescrittoreServer); exit(1); } /* int listen (int descrittore_socket, int dimensione_coda) */ listen(DescrittoreServer, 5); LunghezzaClient = sizeof(cli_addr); while(1){ /* int accept(int descrittore_socket, struct sockaddr* indirizzo, int* lunghezza_record_indirizzo) */ DescrittoreClient = accept(DescrittoreServer, (struct sockaddr *) &cli_addr, &LunghezzaClient); if(DescrittoreClient < 0){ perror("Errore: non è possibile stabilire la connessione\n"); close(DescrittoreServer); close(DescrittoreClient); exit(1); } /* get the file name from the client */ rc = recv(DescrittoreClient, filename, sizeof(filename), 0); if (rc == -1) { fprintf(stderr, "recv failed: %s\n", strerror(errno)); exit(1); } /* Terminiamo il nome del file con NULL e se ultimo carattere è \n o \r lo cambiamo con Codice del client:
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <sys/types.h> #include <netdb.h> #include <fcntl.h> #include <stdint.h> #include <inttypes.h> int main(int argc, char *argv[]){ /* Controllo che vi sia argv[0], argv[1] e argv[2] */ if(argc != 4){ printf("Uso: ./client <hostname> <numero porta> <nomefile>\n"); exit(1); } int DescrittoreClient, fd; /* descrittore del socket */ int NumPorta = atoi(argv[2]); /* numero di porta */ struct sockaddr_in serv_addr; /* indirizzo del server */ char nread=0, Buffer[1024] = {}; /* contiene i dati di invio e ricezione */ struct hostent *hp; /* con la struttura hostent definisco l'hostname del server */ char *filename = argv[3]; size_t fsize; int tmp=0, bytes_read; hp = gethostbyname(argv[1]); bzero((char *) &serv_addr, sizeof(serv_addr)); /* bzero scrive dei null bytes dove specificato per la lunghezza specificata */ serv_addr.sin_family = AF_INET; /* la famiglia dei protocolli */ serv_addr.sin_port = htons(NumPorta); /* la porta */ serv_addr.sin_addr.s_addr = ((struct in_addr*)(hp->h_addr)) -> s_addr; /* memorizzo il tutto nella struttura serv_addr */ DescrittoreClient = socket(AF_INET, SOCK_STREAM, 0); if(DescrittoreClient < 0){ perror("Errore nella creazione della socket"); exit(1); } connect(DescrittoreClient, (struct sockaddr *) &serv_addr, sizeof(serv_addr)); if(connect < 0){ perror("Errore nella connessione"); close(DescrittoreClient); exit(1); } strcpy(Buffer, filename); send(DescrittoreClient, Buffer, strlen(Buffer), 0); bytes_read = read(DescrittoreClient, &fsize, sizeof(fsize)); if(bytes_read == -1){ printf("Errore durante ricezione grandezza file\n"); close(DescrittoreClient); exit(1); } fd = open(filename, O_CREAT | O_WRONLY,0644); if (fd < 0) { perror("open"); exit(1); } while(nread != bytes_read){ while ((nread = read(DescrittoreClient, Buffer, sizeof(Buffer))) > 0){ write(fd, Buffer, nread); tmp+=nread; } } printf("File ricevuto\n"); close(DescrittoreClient); return EXIT_SUCCESS; }
e codice del server:
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <sys/types.h> #include <netdb.h> #include <errno.h> #include <fcntl.h> #include <sys/sendfile.h> #include <sys/stat.h> int main(int argc, char *argv[]){ if(argc != 2){ printf("Uso: ./server <numero porta>\n"); exit(1); } int DescrittoreServer, DescrittoreClient, LunghezzaClient; int NumPorta = atoi(argv[1]); struct sockaddr_in serv_addr, cli_addr; /* indirizzo del server e del client */ char Buffer[1024] = {}; int rc, fd, bytes_sent; off_t offset = 0; struct stat stat_buf; char filename[1024] = {}; size_t fsize; DescrittoreServer = socket(AF_INET, SOCK_STREAM, 0); if(DescrittoreServer < 0){ perror("Errore creazione socket\n"); exit(1); } bzero((char *) &serv_addr, sizeof(serv_addr)); /* bzero scrive dei null bytes dove specificato per la lunghezza specificata */ serv_addr.sin_family = AF_INET; /* la famiglia dei protocolli */ serv_addr.sin_port = htons(NumPorta); /* porta htons converte nell'ordine dei byte di rete */ serv_addr.sin_addr.s_addr = INADDR_ANY; /* dato che è un server bisogna associargli l'indirizzo della macchina su cui sta girando */ /* int bind(int descrittore_socket, struct sockaddr* indirizzo, int lunghezza_record_indirizzo) */ if(bind(DescrittoreServer, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0){ perror("Errore di bind\n"); close(DescrittoreServer); exit(1); } /* int listen (int descrittore_socket, int dimensione_coda) */ listen(DescrittoreServer, 5); LunghezzaClient = sizeof(cli_addr); while(1){ /* int accept(int descrittore_socket, struct sockaddr* indirizzo, int* lunghezza_record_indirizzo) */ DescrittoreClient = accept(DescrittoreServer, (struct sockaddr *) &cli_addr, &LunghezzaClient); if(DescrittoreClient < 0){ perror("Errore: non è possibile stabilire la connessione\n"); close(DescrittoreServer); close(DescrittoreClient); exit(1); } /* get the file name from the client */ rc = recv(DescrittoreClient, filename, sizeof(filename), 0); if (rc == -1) { fprintf(stderr, "recv failed: %s\n", strerror(errno)); exit(1); } /* Terminiamo il nome del file con NULL e se ultimo carattere è \n o \r lo cambiamo con {parsed_message}*/ filename[rc] = '{parsed_message}'; if (filename[strlen(filename)-1] == '\n') filename[strlen(filename)-1] = '{parsed_message}'; if (filename[strlen(filename)-1] == '\r') filename[strlen(filename)-1] = '{parsed_message}'; fprintf(stderr, "Ricevuta richiesta di inviare il file: '%s'\n", filename); /* open the file to be sent */ fd = open(filename, O_RDONLY); if (fd == -1) { fprintf(stderr, "Impossibile aprire '%s': %s\n", filename, strerror(errno)); exit(1); } /* get the size of the file to be sent */ fstat(fd, &stat_buf); fsize = stat_buf.st_size; bytes_sent = send(DescrittoreClient, &fsize, sizeof(fsize), 0); if(bytes_sent == -1){ print("Errore durante l'invio della grandezza del file\n"); close(DescrittoreClient); close(fd); close(DescrittoreServer); exit(1); } /* copy file using sendfile */ offset = 0; rc = sendfile(DescrittoreClient, fd, &offset, stat_buf.st_size); if (rc == -1) { fprintf(stderr, "Errore durante l'invio di: '%s'\n", strerror(errno)); exit(1); } if (rc != stat_buf.st_size) { fprintf(stderr, "Trasferimento incompleto: %d di %d bytes\n", rc, (int)stat_buf.st_size); exit(1); } char *ip_address = inet_ntoa(cli_addr.sin_addr); /* inet_ntoa converte un hostname in un ip */ printf("IP del client: %s\n", ip_address); close(DescrittoreClient); close(fd); } close(DescrittoreServer); return EXIT_SUCCESS; }
Come funziona questo programma?
1) client manda nome file al server
2) server manda grandezza file al client
3) server manda il file
4) il client riceve il file
Qual è il problema?
Per esempio sto cercando di copiare un file "prova.txt" grande 2143 bytes, il client riceve la grandezza (2143) e quindi inzia a ricevere il file solo che il client "si blocca" in modalità ricezione e consuma MOLTA cpu!
Inoltre file ricevuto ha una grandezza di 95 byte
Perchè accade ciò? */ filename[rc] = 'Codice del client:
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <sys/types.h> #include <netdb.h> #include <fcntl.h> #include <stdint.h> #include <inttypes.h> int main(int argc, char *argv[]){ /* Controllo che vi sia argv[0], argv[1] e argv[2] */ if(argc != 4){ printf("Uso: ./client <hostname> <numero porta> <nomefile>\n"); exit(1); } int DescrittoreClient, fd; /* descrittore del socket */ int NumPorta = atoi(argv[2]); /* numero di porta */ struct sockaddr_in serv_addr; /* indirizzo del server */ char nread=0, Buffer[1024] = {}; /* contiene i dati di invio e ricezione */ struct hostent *hp; /* con la struttura hostent definisco l'hostname del server */ char *filename = argv[3]; size_t fsize; int tmp=0, bytes_read; hp = gethostbyname(argv[1]); bzero((char *) &serv_addr, sizeof(serv_addr)); /* bzero scrive dei null bytes dove specificato per la lunghezza specificata */ serv_addr.sin_family = AF_INET; /* la famiglia dei protocolli */ serv_addr.sin_port = htons(NumPorta); /* la porta */ serv_addr.sin_addr.s_addr = ((struct in_addr*)(hp->h_addr)) -> s_addr; /* memorizzo il tutto nella struttura serv_addr */ DescrittoreClient = socket(AF_INET, SOCK_STREAM, 0); if(DescrittoreClient < 0){ perror("Errore nella creazione della socket"); exit(1); } connect(DescrittoreClient, (struct sockaddr *) &serv_addr, sizeof(serv_addr)); if(connect < 0){ perror("Errore nella connessione"); close(DescrittoreClient); exit(1); } strcpy(Buffer, filename); send(DescrittoreClient, Buffer, strlen(Buffer), 0); bytes_read = read(DescrittoreClient, &fsize, sizeof(fsize)); if(bytes_read == -1){ printf("Errore durante ricezione grandezza file\n"); close(DescrittoreClient); exit(1); } fd = open(filename, O_CREAT | O_WRONLY,0644); if (fd < 0) { perror("open"); exit(1); } while(nread != bytes_read){ while ((nread = read(DescrittoreClient, Buffer, sizeof(Buffer))) > 0){ write(fd, Buffer, nread); tmp+=nread; } } printf("File ricevuto\n"); close(DescrittoreClient); return EXIT_SUCCESS; }
e codice del server:
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <sys/types.h> #include <netdb.h> #include <errno.h> #include <fcntl.h> #include <sys/sendfile.h> #include <sys/stat.h> int main(int argc, char *argv[]){ if(argc != 2){ printf("Uso: ./server <numero porta>\n"); exit(1); } int DescrittoreServer, DescrittoreClient, LunghezzaClient; int NumPorta = atoi(argv[1]); struct sockaddr_in serv_addr, cli_addr; /* indirizzo del server e del client */ char Buffer[1024] = {}; int rc, fd, bytes_sent; off_t offset = 0; struct stat stat_buf; char filename[1024] = {}; size_t fsize; DescrittoreServer = socket(AF_INET, SOCK_STREAM, 0); if(DescrittoreServer < 0){ perror("Errore creazione socket\n"); exit(1); } bzero((char *) &serv_addr, sizeof(serv_addr)); /* bzero scrive dei null bytes dove specificato per la lunghezza specificata */ serv_addr.sin_family = AF_INET; /* la famiglia dei protocolli */ serv_addr.sin_port = htons(NumPorta); /* porta htons converte nell'ordine dei byte di rete */ serv_addr.sin_addr.s_addr = INADDR_ANY; /* dato che è un server bisogna associargli l'indirizzo della macchina su cui sta girando */ /* int bind(int descrittore_socket, struct sockaddr* indirizzo, int lunghezza_record_indirizzo) */ if(bind(DescrittoreServer, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0){ perror("Errore di bind\n"); close(DescrittoreServer); exit(1); } /* int listen (int descrittore_socket, int dimensione_coda) */ listen(DescrittoreServer, 5); LunghezzaClient = sizeof(cli_addr); while(1){ /* int accept(int descrittore_socket, struct sockaddr* indirizzo, int* lunghezza_record_indirizzo) */ DescrittoreClient = accept(DescrittoreServer, (struct sockaddr *) &cli_addr, &LunghezzaClient); if(DescrittoreClient < 0){ perror("Errore: non è possibile stabilire la connessione\n"); close(DescrittoreServer); close(DescrittoreClient); exit(1); } /* get the file name from the client */ rc = recv(DescrittoreClient, filename, sizeof(filename), 0); if (rc == -1) { fprintf(stderr, "recv failed: %s\n", strerror(errno)); exit(1); } /* Terminiamo il nome del file con NULL e se ultimo carattere è \n o \r lo cambiamo con {parsed_message}*/ filename[rc] = '{parsed_message}'; if (filename[strlen(filename)-1] == '\n') filename[strlen(filename)-1] = '{parsed_message}'; if (filename[strlen(filename)-1] == '\r') filename[strlen(filename)-1] = '{parsed_message}'; fprintf(stderr, "Ricevuta richiesta di inviare il file: '%s'\n", filename); /* open the file to be sent */ fd = open(filename, O_RDONLY); if (fd == -1) { fprintf(stderr, "Impossibile aprire '%s': %s\n", filename, strerror(errno)); exit(1); } /* get the size of the file to be sent */ fstat(fd, &stat_buf); fsize = stat_buf.st_size; bytes_sent = send(DescrittoreClient, &fsize, sizeof(fsize), 0); if(bytes_sent == -1){ print("Errore durante l'invio della grandezza del file\n"); close(DescrittoreClient); close(fd); close(DescrittoreServer); exit(1); } /* copy file using sendfile */ offset = 0; rc = sendfile(DescrittoreClient, fd, &offset, stat_buf.st_size); if (rc == -1) { fprintf(stderr, "Errore durante l'invio di: '%s'\n", strerror(errno)); exit(1); } if (rc != stat_buf.st_size) { fprintf(stderr, "Trasferimento incompleto: %d di %d bytes\n", rc, (int)stat_buf.st_size); exit(1); } char *ip_address = inet_ntoa(cli_addr.sin_addr); /* inet_ntoa converte un hostname in un ip */ printf("IP del client: %s\n", ip_address); close(DescrittoreClient); close(fd); } close(DescrittoreServer); return EXIT_SUCCESS; }
Come funziona questo programma?
1) client manda nome file al server
2) server manda grandezza file al client
3) server manda il file
4) il client riceve il file
Qual è il problema?
Per esempio sto cercando di copiare un file "prova.txt" grande 2143 bytes, il client riceve la grandezza (2143) e quindi inzia a ricevere il file solo che il client "si blocca" in modalità ricezione e consuma MOLTA cpu!
Inoltre file ricevuto ha una grandezza di 95 byte
Perchè accade ciò? '; if (filename[strlen(filename)-1] == '\n') filename[strlen(filename)-1] = 'Codice del client:
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <sys/types.h> #include <netdb.h> #include <fcntl.h> #include <stdint.h> #include <inttypes.h> int main(int argc, char *argv[]){ /* Controllo che vi sia argv[0], argv[1] e argv[2] */ if(argc != 4){ printf("Uso: ./client <hostname> <numero porta> <nomefile>\n"); exit(1); } int DescrittoreClient, fd; /* descrittore del socket */ int NumPorta = atoi(argv[2]); /* numero di porta */ struct sockaddr_in serv_addr; /* indirizzo del server */ char nread=0, Buffer[1024] = {}; /* contiene i dati di invio e ricezione */ struct hostent *hp; /* con la struttura hostent definisco l'hostname del server */ char *filename = argv[3]; size_t fsize; int tmp=0, bytes_read; hp = gethostbyname(argv[1]); bzero((char *) &serv_addr, sizeof(serv_addr)); /* bzero scrive dei null bytes dove specificato per la lunghezza specificata */ serv_addr.sin_family = AF_INET; /* la famiglia dei protocolli */ serv_addr.sin_port = htons(NumPorta); /* la porta */ serv_addr.sin_addr.s_addr = ((struct in_addr*)(hp->h_addr)) -> s_addr; /* memorizzo il tutto nella struttura serv_addr */ DescrittoreClient = socket(AF_INET, SOCK_STREAM, 0); if(DescrittoreClient < 0){ perror("Errore nella creazione della socket"); exit(1); } connect(DescrittoreClient, (struct sockaddr *) &serv_addr, sizeof(serv_addr)); if(connect < 0){ perror("Errore nella connessione"); close(DescrittoreClient); exit(1); } strcpy(Buffer, filename); send(DescrittoreClient, Buffer, strlen(Buffer), 0); bytes_read = read(DescrittoreClient, &fsize, sizeof(fsize)); if(bytes_read == -1){ printf("Errore durante ricezione grandezza file\n"); close(DescrittoreClient); exit(1); } fd = open(filename, O_CREAT | O_WRONLY,0644); if (fd < 0) { perror("open"); exit(1); } while(nread != bytes_read){ while ((nread = read(DescrittoreClient, Buffer, sizeof(Buffer))) > 0){ write(fd, Buffer, nread); tmp+=nread; } } printf("File ricevuto\n"); close(DescrittoreClient); return EXIT_SUCCESS; }
e codice del server:
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <sys/types.h> #include <netdb.h> #include <errno.h> #include <fcntl.h> #include <sys/sendfile.h> #include <sys/stat.h> int main(int argc, char *argv[]){ if(argc != 2){ printf("Uso: ./server <numero porta>\n"); exit(1); } int DescrittoreServer, DescrittoreClient, LunghezzaClient; int NumPorta = atoi(argv[1]); struct sockaddr_in serv_addr, cli_addr; /* indirizzo del server e del client */ char Buffer[1024] = {}; int rc, fd, bytes_sent; off_t offset = 0; struct stat stat_buf; char filename[1024] = {}; size_t fsize; DescrittoreServer = socket(AF_INET, SOCK_STREAM, 0); if(DescrittoreServer < 0){ perror("Errore creazione socket\n"); exit(1); } bzero((char *) &serv_addr, sizeof(serv_addr)); /* bzero scrive dei null bytes dove specificato per la lunghezza specificata */ serv_addr.sin_family = AF_INET; /* la famiglia dei protocolli */ serv_addr.sin_port = htons(NumPorta); /* porta htons converte nell'ordine dei byte di rete */ serv_addr.sin_addr.s_addr = INADDR_ANY; /* dato che è un server bisogna associargli l'indirizzo della macchina su cui sta girando */ /* int bind(int descrittore_socket, struct sockaddr* indirizzo, int lunghezza_record_indirizzo) */ if(bind(DescrittoreServer, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0){ perror("Errore di bind\n"); close(DescrittoreServer); exit(1); } /* int listen (int descrittore_socket, int dimensione_coda) */ listen(DescrittoreServer, 5); LunghezzaClient = sizeof(cli_addr); while(1){ /* int accept(int descrittore_socket, struct sockaddr* indirizzo, int* lunghezza_record_indirizzo) */ DescrittoreClient = accept(DescrittoreServer, (struct sockaddr *) &cli_addr, &LunghezzaClient); if(DescrittoreClient < 0){ perror("Errore: non è possibile stabilire la connessione\n"); close(DescrittoreServer); close(DescrittoreClient); exit(1); } /* get the file name from the client */ rc = recv(DescrittoreClient, filename, sizeof(filename), 0); if (rc == -1) { fprintf(stderr, "recv failed: %s\n", strerror(errno)); exit(1); } /* Terminiamo il nome del file con NULL e se ultimo carattere è \n o \r lo cambiamo con {parsed_message}*/ filename[rc] = '{parsed_message}'; if (filename[strlen(filename)-1] == '\n') filename[strlen(filename)-1] = '{parsed_message}'; if (filename[strlen(filename)-1] == '\r') filename[strlen(filename)-1] = '{parsed_message}'; fprintf(stderr, "Ricevuta richiesta di inviare il file: '%s'\n", filename); /* open the file to be sent */ fd = open(filename, O_RDONLY); if (fd == -1) { fprintf(stderr, "Impossibile aprire '%s': %s\n", filename, strerror(errno)); exit(1); } /* get the size of the file to be sent */ fstat(fd, &stat_buf); fsize = stat_buf.st_size; bytes_sent = send(DescrittoreClient, &fsize, sizeof(fsize), 0); if(bytes_sent == -1){ print("Errore durante l'invio della grandezza del file\n"); close(DescrittoreClient); close(fd); close(DescrittoreServer); exit(1); } /* copy file using sendfile */ offset = 0; rc = sendfile(DescrittoreClient, fd, &offset, stat_buf.st_size); if (rc == -1) { fprintf(stderr, "Errore durante l'invio di: '%s'\n", strerror(errno)); exit(1); } if (rc != stat_buf.st_size) { fprintf(stderr, "Trasferimento incompleto: %d di %d bytes\n", rc, (int)stat_buf.st_size); exit(1); } char *ip_address = inet_ntoa(cli_addr.sin_addr); /* inet_ntoa converte un hostname in un ip */ printf("IP del client: %s\n", ip_address); close(DescrittoreClient); close(fd); } close(DescrittoreServer); return EXIT_SUCCESS; }
Come funziona questo programma?
1) client manda nome file al server
2) server manda grandezza file al client
3) server manda il file
4) il client riceve il file
Qual è il problema?
Per esempio sto cercando di copiare un file "prova.txt" grande 2143 bytes, il client riceve la grandezza (2143) e quindi inzia a ricevere il file solo che il client "si blocca" in modalità ricezione e consuma MOLTA cpu!
Inoltre file ricevuto ha una grandezza di 95 byte
Perchè accade ciò? '; if (filename[strlen(filename)-1] == '\r') filename[strlen(filename)-1] = 'Codice del client:
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <sys/types.h> #include <netdb.h> #include <fcntl.h> #include <stdint.h> #include <inttypes.h> int main(int argc, char *argv[]){ /* Controllo che vi sia argv[0], argv[1] e argv[2] */ if(argc != 4){ printf("Uso: ./client <hostname> <numero porta> <nomefile>\n"); exit(1); } int DescrittoreClient, fd; /* descrittore del socket */ int NumPorta = atoi(argv[2]); /* numero di porta */ struct sockaddr_in serv_addr; /* indirizzo del server */ char nread=0, Buffer[1024] = {}; /* contiene i dati di invio e ricezione */ struct hostent *hp; /* con la struttura hostent definisco l'hostname del server */ char *filename = argv[3]; size_t fsize; int tmp=0, bytes_read; hp = gethostbyname(argv[1]); bzero((char *) &serv_addr, sizeof(serv_addr)); /* bzero scrive dei null bytes dove specificato per la lunghezza specificata */ serv_addr.sin_family = AF_INET; /* la famiglia dei protocolli */ serv_addr.sin_port = htons(NumPorta); /* la porta */ serv_addr.sin_addr.s_addr = ((struct in_addr*)(hp->h_addr)) -> s_addr; /* memorizzo il tutto nella struttura serv_addr */ DescrittoreClient = socket(AF_INET, SOCK_STREAM, 0); if(DescrittoreClient < 0){ perror("Errore nella creazione della socket"); exit(1); } connect(DescrittoreClient, (struct sockaddr *) &serv_addr, sizeof(serv_addr)); if(connect < 0){ perror("Errore nella connessione"); close(DescrittoreClient); exit(1); } strcpy(Buffer, filename); send(DescrittoreClient, Buffer, strlen(Buffer), 0); bytes_read = read(DescrittoreClient, &fsize, sizeof(fsize)); if(bytes_read == -1){ printf("Errore durante ricezione grandezza file\n"); close(DescrittoreClient); exit(1); } fd = open(filename, O_CREAT | O_WRONLY,0644); if (fd < 0) { perror("open"); exit(1); } while(nread != bytes_read){ while ((nread = read(DescrittoreClient, Buffer, sizeof(Buffer))) > 0){ write(fd, Buffer, nread); tmp+=nread; } } printf("File ricevuto\n"); close(DescrittoreClient); return EXIT_SUCCESS; }
e codice del server:
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <sys/types.h> #include <netdb.h> #include <errno.h> #include <fcntl.h> #include <sys/sendfile.h> #include <sys/stat.h> int main(int argc, char *argv[]){ if(argc != 2){ printf("Uso: ./server <numero porta>\n"); exit(1); } int DescrittoreServer, DescrittoreClient, LunghezzaClient; int NumPorta = atoi(argv[1]); struct sockaddr_in serv_addr, cli_addr; /* indirizzo del server e del client */ char Buffer[1024] = {}; int rc, fd, bytes_sent; off_t offset = 0; struct stat stat_buf; char filename[1024] = {}; size_t fsize; DescrittoreServer = socket(AF_INET, SOCK_STREAM, 0); if(DescrittoreServer < 0){ perror("Errore creazione socket\n"); exit(1); } bzero((char *) &serv_addr, sizeof(serv_addr)); /* bzero scrive dei null bytes dove specificato per la lunghezza specificata */ serv_addr.sin_family = AF_INET; /* la famiglia dei protocolli */ serv_addr.sin_port = htons(NumPorta); /* porta htons converte nell'ordine dei byte di rete */ serv_addr.sin_addr.s_addr = INADDR_ANY; /* dato che è un server bisogna associargli l'indirizzo della macchina su cui sta girando */ /* int bind(int descrittore_socket, struct sockaddr* indirizzo, int lunghezza_record_indirizzo) */ if(bind(DescrittoreServer, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0){ perror("Errore di bind\n"); close(DescrittoreServer); exit(1); } /* int listen (int descrittore_socket, int dimensione_coda) */ listen(DescrittoreServer, 5); LunghezzaClient = sizeof(cli_addr); while(1){ /* int accept(int descrittore_socket, struct sockaddr* indirizzo, int* lunghezza_record_indirizzo) */ DescrittoreClient = accept(DescrittoreServer, (struct sockaddr *) &cli_addr, &LunghezzaClient); if(DescrittoreClient < 0){ perror("Errore: non è possibile stabilire la connessione\n"); close(DescrittoreServer); close(DescrittoreClient); exit(1); } /* get the file name from the client */ rc = recv(DescrittoreClient, filename, sizeof(filename), 0); if (rc == -1) { fprintf(stderr, "recv failed: %s\n", strerror(errno)); exit(1); } /* Terminiamo il nome del file con NULL e se ultimo carattere è \n o \r lo cambiamo con {parsed_message}*/ filename[rc] = '{parsed_message}'; if (filename[strlen(filename)-1] == '\n') filename[strlen(filename)-1] = '{parsed_message}'; if (filename[strlen(filename)-1] == '\r') filename[strlen(filename)-1] = '{parsed_message}'; fprintf(stderr, "Ricevuta richiesta di inviare il file: '%s'\n", filename); /* open the file to be sent */ fd = open(filename, O_RDONLY); if (fd == -1) { fprintf(stderr, "Impossibile aprire '%s': %s\n", filename, strerror(errno)); exit(1); } /* get the size of the file to be sent */ fstat(fd, &stat_buf); fsize = stat_buf.st_size; bytes_sent = send(DescrittoreClient, &fsize, sizeof(fsize), 0); if(bytes_sent == -1){ print("Errore durante l'invio della grandezza del file\n"); close(DescrittoreClient); close(fd); close(DescrittoreServer); exit(1); } /* copy file using sendfile */ offset = 0; rc = sendfile(DescrittoreClient, fd, &offset, stat_buf.st_size); if (rc == -1) { fprintf(stderr, "Errore durante l'invio di: '%s'\n", strerror(errno)); exit(1); } if (rc != stat_buf.st_size) { fprintf(stderr, "Trasferimento incompleto: %d di %d bytes\n", rc, (int)stat_buf.st_size); exit(1); } char *ip_address = inet_ntoa(cli_addr.sin_addr); /* inet_ntoa converte un hostname in un ip */ printf("IP del client: %s\n", ip_address); close(DescrittoreClient); close(fd); } close(DescrittoreServer); return EXIT_SUCCESS; }
Come funziona questo programma?
1) client manda nome file al server
2) server manda grandezza file al client
3) server manda il file
4) il client riceve il file
Qual è il problema?
Per esempio sto cercando di copiare un file "prova.txt" grande 2143 bytes, il client riceve la grandezza (2143) e quindi inzia a ricevere il file solo che il client "si blocca" in modalità ricezione e consuma MOLTA cpu!
Inoltre file ricevuto ha una grandezza di 95 byte
Perchè accade ciò? '; fprintf(stderr, "Ricevuta richiesta di inviare il file: '%s'\n", filename); /* open the file to be sent */ fd = open(filename, O_RDONLY); if (fd == -1) { fprintf(stderr, "Impossibile aprire '%s': %s\n", filename, strerror(errno)); exit(1); } /* get the size of the file to be sent */ fstat(fd, &stat_buf); fsize = stat_buf.st_size; bytes_sent = send(DescrittoreClient, &fsize, sizeof(fsize), 0); if(bytes_sent == -1){ print("Errore durante l'invio della grandezza del file\n"); close(DescrittoreClient); close(fd); close(DescrittoreServer); exit(1); } /* copy file using sendfile */ offset = 0; rc = sendfile(DescrittoreClient, fd, &offset, stat_buf.st_size); if (rc == -1) { fprintf(stderr, "Errore durante l'invio di: '%s'\n", strerror(errno)); exit(1); } if (rc != stat_buf.st_size) { fprintf(stderr, "Trasferimento incompleto: %d di %d bytes\n", rc, (int)stat_buf.st_size); exit(1); } char *ip_address = inet_ntoa(cli_addr.sin_addr); /* inet_ntoa converte un hostname in un ip */ printf("IP del client: %s\n", ip_address); close(DescrittoreClient); close(fd); } close(DescrittoreServer); return EXIT_SUCCESS; }
Come funziona questo programma?
1) client manda nome file al server
2) server manda grandezza file al client
3) server manda il file
4) il client riceve il file
Qual è il problema?
Per esempio sto cercando di copiare un file "prova.txt" grande 2143 bytes, il client riceve la grandezza (2143) e quindi inzia a ricevere il file solo che il client "si blocca" in modalità ricezione e consuma MOLTA cpu!
Inoltre file ricevuto ha una grandezza di 95 byte
Perchè accade ciò?
aaa