codice:
--------CLIENT-------
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <string.h>
#include <fcntl.h>
#define BUFSIZE 1024
#define max(a,b) ((a) > (b) ? (a) : (b))
int scelta_file(int sock);
void sceltaFileStreaming(int sock, char *buffer);
int main(int argc, char **argv)
{
int scelta, sock, n;
char recvline[1025];
struct sockaddr_in serv_add;
char **alias;
char *addr;
struct hostent *data;
char buffer[BUFSIZE],PRONTO[2];
int fd,k,size,nread,maxfd,addrlen;
fd_set fset;
// Variabile per contare i byte inviati
size=0;
// Variabile per la gestione di pausa, ripresa e terminazione del client
// Se k=0 --> ricevo normalmente il file
// Se k=1 --> il client ha deciso di mettere in pausa il download
k=0;
if (argc != 2)
{
fprintf(stderr,"usage: %s <IPaddress>\n",argv[0]);
exit (1);
}
//SOCKET
if ( (sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
fprintf(stderr,"socket error\n");
exit (1);
}
//SIN_FAMILY
serv_add.sin_family = AF_INET;
//SIN_PORT
serv_add.sin_port = htons(1121);
data = gethostbyname(argv[1]);
if (data == NULL) {
herror("Errore di risoluzione");
exit(1);
}
alias = data->h_addr_list;
addr = (char *)inet_ntop(data->h_addrtype, *alias, buffer, sizeof(buffer));
if (inet_pton(AF_INET, addr, &serv_add.sin_addr) < 0) {
fprintf(stderr,"inet_pton error for %s\n", argv[1]);
exit (1);
}
//CONNECT
if (connect(sock, (struct sockaddr *) &serv_add, sizeof(serv_add)) < 0) {
fprintf(stderr,"connect error\n");
exit(1);
}
//WHILE READ
while ( (n = read(sock, recvline, 1024)) > 0) {
recvline[n] = 0;
if (fputs(recvline, stdout) == EOF) {
fprintf(stderr,"fputs error\n");
exit(1);
}
if (n < 0) {
fprintf(stderr,"read error\n");
exit(1);
}
scelta=scelta_file(sock);
if (scelta==0){
printf("\nIl tasto scelto ha terminato il servizio streaming.\n\n-------------------------------\nLoading...\n");
sleep(2);
close(sock);
exit(0);
}
else
memset(buffer, 0, BUFSIZE);//puliamo il buffer
sceltaFileStreaming(sock,buffer);
if (read(sock,buffer,strlen(buffer))<0)
{
perror (" read error ");
exit ( -1);
}
fd = open(buffer, O_CREAT | O_WRONLY,0700);
memset(buffer,0,BUFSIZE);
if (fd < 0)
{
perror(" open error");
exit(1);
}
FD_ZERO(&fset);
while(1){
/* Se k=0 allora possiamo settare il descrittore del socket
in quanto non ci sono interruzioni del client
e il download avviene normalmente */
if(k==0)
FD_SET(sock,&fset);
/* Setto il descrittore dello standard input per controllare
se ci sono tasti digitati da tastiera durante il download */
FD_SET(fileno(stdin),&fset);
maxfd=max(sock,fileno(stdin))+1;
select(maxfd,&fset, NULL, NULL, NULL);
/* Usciti dalla select controlliamo se e' stato digitato qualche tasto
e controlliamo l'azione da intraprendere */
if(FD_ISSET(fileno(stdin),&fset)){
fgets(buffer, BUFSIZE, stdin);
/* E' stata digitata una 'P' che sta ad indicare il mettere in pausa
il download. Quindi 'puliamo' il descrittore del socket, settiamo k=1
e in tal modo mettiamo in pausa il trasferimento dati ed inviamo al server
la P inserita sul socket */
if(buffer[0]=='P'){
FD_CLR(sock,&fset);
k=1;
fflush(stdin);
printf("\nHai interrotto il dowload. Ricevuti : %d byte. \nPremere 'R' per riprendere, 'S' per uscire.\n\n",size);
if(write(sock, buffer, strlen(buffer))<0)
{
perror (" write error ");
exit ( -1);
}
}
/* E' stata digitata una 'R' che sta ad indicare la volonta'
di riprendere il download. Quindi settiamo k=0 per
'riattivare' il descrittore del socket e riprendiamo il trasferimento.
Comunichiamo la R al server sul socket */
if(buffer[0]=='R'){
k=0;
printf("\nRiprendo il download... \nPremere 'P' per mettere in pausa, 'S' per uscire.\n\n");
if(write(sock, buffer, sizeof(buffer))<0)
{
perror (" write error ");
exit ( -1);
}
}
/* E' stata digitata una 'S'. Si vuole terminare senza aver completato il
download. Quindi inviamo la S tramite socket al server, chiudiamo
la connessione ed usciamo dal client */
if(buffer[0]=='S'){
printf("\nTermine forzato del download... \nConnessione chiusa.\n\n");
if(write(sock, buffer, strlen(buffer))<0)
{
perror (" write error ");
exit ( -1);
}
sleep(2);
close(sock);
exit(0);
}
memset (buffer, 0, BUFSIZE);
}
}
/* Controlliamo se ci sono ancora dati da leggere sul socket */
if(FD_ISSET(sock,&fset)){
nread=recvfrom(sock, buffer, BUFSIZE, 0, (struct sockaddr *)&serv_add, &addrlen);
size+=nread;
if(nread<0){
perror("recvfrom error");
exit(1);
}
/* Se non ci sono più dati allora il download e' andato a buon fine.
Quindi chiudiamo la connessione ed usciamo dal client */
if(nread==0){
printf("\nDownload Completato.\nRicevuti %d byte.\n\n",size);
close(sock);
exit(0);
}
/* Se il download non e' completato scriviamo i byte letti sul file aperto
in scrittura */
if(write(fd,buffer,BUFSIZE)<0)
{
perror (" write error ");
exit ( -1);
}
}
exit(0);
}
}
int scelta_file (int sock)
{
char buffer[1024];
int scelta;
memset(buffer, 0, sizeof(buffer)); /*puliamo il buffer*/
/*leggiamo e stampiamo il buffer per la scelta*/
if(read(sock,buffer,sizeof(buffer))<0)//legge lista
{
perror (" read error ");
exit ( -1);
}
printf("%s\n",buffer);
/*alla richiesta del server digitiamo la nostra scelta
e la inviamo al server*/
scanf("%d",&scelta);
if(write(sock,&scelta,sizeof(scelta))<0) //invia scelta al server
{
perror (" write error ");
exit ( -1);
}
return scelta;
}
void sceltaFileStreaming(int sock,char *buffer)
{
if(read(sock,buffer,BUFSIZE)<0) //leggiamo dal server il file scelto
{
perror (" read error ");
exit ( -1);
}
printf("Hai scelto di scaricare:\n%s \nLoading...\n",buffer);//stampa messaggio
if (strlen(buffer)>70)
{
sleep(2);
close(sock);
exit(0);
}
sleep(1);
printf("\nPremere 'P' per la pausa, 'S' per uscire.\n\n");
printf("Download in corso...\n");
}