Ejemplo n.º 1
0
/**
  * @brief Main
  * @return Ritorna un intero.
 */
int main(int argc, char *argv[])
{
	
	/* Inizializzazione delle variabili */
	index = 0;
	lPkt = NULL;
	contACK = 0;
	tipoCnt = 0;

	printf ("uso i parametri di default \n%s\n", PARAMETRIDEFAULT );
	localportfrommobile = 6001;
	localportdatamonitor = 7001;
	portmonitor = 8000;
	
	/* Inizializzazione dei vettori */
	initV(cfgPKT);
	initV(tipoConn);
	initV(pktTipoConn);
	
	init_random();

	/* Si connette al monitor */
	ris=TCP_setup_connection(&monitorfd, "127.0.0.1", portmonitor,  300000, 300000, 1);
	if(!ris) {	printf ("TCP_setup_connection() failed\n"); exit(1); }
	else printf("monitorfd %d\n", monitorfd);

	FD_ZERO(&all);
	FD_SET(monitorfd,&all);
	maxfd=monitorfd;

	ris=RecvCfg(monitorfd,&numporte,porte);
	if(!ris) {	printf ("RecvCfg() failed\n"); exit(1); }
	for(i=0;i<numporte;i++) {
		cfgPorte[i]=porte[i];
	}

	/* Creazione del pacchetto della configurazione delle porte */
	config_pkt_porte(cfgPKT, numporte);
	
	ris=UDP_setup_socket_bound( &monitordatafd, localportdatamonitor, 65535, 65535 );
	if (!ris) {	printf ("UDP_setup_socket_bound() failed\n"); exit(1); }
	FD_SET(monitordatafd,&all);
	if(monitordatafd>maxfd)
		maxfd=monitordatafd;

	appmobilefd=0;
	/* Attende la connessione dall'applicazione lato mobile */
	ris=TCP_setup_socket_listening( &listening_mobilefd, localportfrommobile, 300000, 300000, 1);
	if (!ris)
	{	printf ("TCP_setup_socket_listening() failed\n");
		exit(1);
	}
	do { memset (&Cli, 0, sizeof (Cli));		
		len = sizeof (Cli);
		appmobilefd = accept ( listening_mobilefd, (struct sockaddr *) &Cli, &len);
	} while ( (appmobilefd<0) && (errno==EINTR) );
	if (appmobilefd < 0 ) {	
		perror("accept() failed: \n");
		exit (1);
	}
	/* NO NAGLE per i tcp */
	ris=SetsockoptTCPNODELAY(appmobilefd,1); if (!ris) { fprintf(stderr,"unable to setup TCPNODELAY option\n"); exit(5); }
	/* chiusura del socket TCP listening e setup dei socket UDP	*/
	close(listening_mobilefd);
	FD_SET(appmobilefd,&all);
	if(appmobilefd>maxfd)
		maxfd=appmobilefd;
		
	/* Imprime il timestamp sul primo pacchetto, ossia fa partire il cronometro */
	gettimeofday(&timePktFirst,NULL);
	memcpy( (char*)&(tipoConn[0]), (char*)&timePktFirst, sizeof(struct timeval) );
	
	/* Controllo del tipo di connessione */
	for(;;)
	{
		do 
		{
			rdset=all;

#ifdef VICDEBUG
			stampa_fd_set("rdset prima",&rdset);
#endif

			ris=select(maxfd+1,&rdset,NULL,NULL,NULL);
		} while( (ris<0) && (errno==EINTR) );
		if(ris<0) 
		{
			perror("select failed: ");
			exit(1);
		}
			
		/* Controlla se sono arrivati pacchetti dall'applicazione */
		if( FD_ISSET(appmobilefd,&rdset) )
		{
			uint32_t buf[PKTSIZE];
			uint32_t idmsg;	
			struct timeval sent, now, tempoimpiegato;
			long int msec;

			/* riceve un pkt */
			/*ris=Readn(appmobilefd,(char*)buf,PKTSIZE);
			if(ris!=PKTSIZE) { fprintf(stderr,"recv from appmobile failed, received %d: ", ris); exit(9); }*/
			ris=Readn(appmobilefd,(char*)buf,sizeof(buf));
			if(ris!=sizeof(buf)) { fprintf(stderr,"recv from appmobile failed, received %d: ", ris); exit(9); }

			/* Appena arriva un pacchetto dall'AppMobile, calcola quanto tempo è passato */
			memcpy( (char*)&sent, (char*)&(tipoConn[0]), sizeof(struct timeval) );
			gettimeofday(&now,NULL);

			tempoimpiegato=differenza(now,sent);
			msec=(tempoimpiegato.tv_sec*1000)+(tempoimpiegato.tv_usec/1000);
			
			idmsg = buf[0];

			/* ID del pkt di connessione è 42, tanto per cambiare */
			pktTipoConn[0] = 42;
			
			/* Può capitare che arrivi il primo pacchetto con 40msec di delay su connessione LENTA */
			/* Se è il primo pacchetto */
			if(idmsg < 1)
			{
				/* E se il primo pacchetto arriva con abbastanza ritardo, vuol dire che la connessione è LENTA */
				if((msec > DELAY_VELOCE) && (msec < DELAY_MUTA))
				{
					tipoCnt = pktTipoConn[1] = CONN_LENTA;
					break;
				}
				/* Altrimenti sarà MUTA */
				else if(msec >= DELAY_MUTA)
				{
					tipoCnt = pktTipoConn[1] = CONN_MUTA;
					break;
				}
			}
			/* Se invece il secondo pacchetto è veloce, vuol dire che siamo nella VELOCE */
			else if(msec <= DELAY_LENTA)
			{
				tipoCnt = pktTipoConn[1] = CONN_VELOCE;
				break;
			}
			/* Altrimenti è LENTA */
			else
			{
				tipoCnt = pktTipoConn[1] = CONN_LENTA;
				break;
			}

		}
	}
	
		/* Invio il tipo di connessione al Fixed su tutte le porte attive per avvertirlo */
		/* Invio il tipo di connessione su ogni porta attiva per ben due volte (per evitare di gestire i suoi NACK) */
		for(k=0; k<2; k++)
		{
			for(i=0; i<numporte; i++)
			{
				ris = send_udp(monitordatafd, (char*)pktTipoConn, sizeof(pktTipoConn) , 1000, "127.0.0.1", cfgPorte[i]);
				if(!(ris))
				{
					fprintf(stderr,"Errore durante l'invio del tipo di connessione!\n");
				}
			}
		}

	send_config(cfgPKT, monitordatafd, cfgPorte, numporte);
	
	/* Configurazione del LBMobile sul tipo di connessione */
	switch(tipoCnt)
	{
		case CONN_MUTA:
		
#ifdef TIPO_CONN
			fprintf(stdout,ROSSO "\n*** Attivazione della connessione MUTA ***\n" DEFAULTCOLOR "\n");
#endif
			
/* *********************************************** MUTA ************************************************** */

	for(;;)
	{
		do {
			rdset=all;

#ifdef VICDEBUG
			stampa_fd_set("rdset prima",&rdset);
#endif

			ris=select(maxfd+1,&rdset,NULL,NULL,NULL);
		} while( (ris<0) && (errno==EINTR) );
		if(ris<0) {
			perror("select failed: ");
			exit(1);
		}

#ifdef VICDEBUG
		stampa_fd_set("rdset dopo",&rdset);
#endif

		/* Lettura dei pacchetti UDP provenienti dal Monitor */
		if(FD_ISSET(monitordatafd,&rdset))
		{
			lettura_pkt_monitor();		
		}

		/* Lettura dei pacchetti TCP (CONF, ACK, NACK) provenienti dal Monitor */
		if( FD_ISSET(monitorfd,&rdset) )
		{
			char ch; int ris;
			uint32_t tmpnumporte;
			uint16_t tmpporte[MAXNUMCONNECTIONS];
			uint32_t idmsg;

			/* ris=recv(monitorfd,buf,65536,MSG_DONTWAIT); */
			ris=recv(monitorfd,&ch,1,0);
			if(ris!=1) { fprintf(stderr,"recv from monitor failed: "); exit(9); }
			
			if(ch=='C')
			{
				/* Ricezione del nuovo numero di porte attive */
				ris=recv(monitorfd,(char*)&tmpnumporte,sizeof(uint32_t),0);
				if(ris!=sizeof(uint32_t)) { fprintf(stderr,"(C)recv_configurazione failed: "); exit(9); }

				/* Ricezione del nuovo vettore di porte attive */
				for(i=0;i<tmpnumporte;i++)
				{
 					ris=recv(monitorfd,&(tmpporte[i]),sizeof(uint16_t),0);
					if(ris!=sizeof(uint16_t)) { fprintf(stderr,"(C%d)recv_configurazione failed: ",i); exit(9); }
				}
				
				/* Aggiorna l'indice della porta a cui stava inviando i pacchetti col nuovo */
				config_new_porte(cfgPorte, tmpporte);

				setup_new_configurazione(&numporte,porte,&tmpnumporte,tmpporte);

				/* Creazione del pacchetto della configurazione delle porte */
				config_pkt_porte(cfgPKT, numporte);
				
				/* Invio della configurazione al Fixed */
				send_config(cfgPKT, monitordatafd, cfgPorte, numporte);

			} 
			else if( ch=='A' )
			{
				ris=recv(monitorfd,(char*)&idmsg,sizeof(uint32_t),0);
				if(ris!=sizeof(uint32_t)) { fprintf(stderr,"(A)recv ack failed: "); exit(9); }

				/* Se arriva un ACK presente nella lista di pacchetti, lo rimuove */
				if(find_id_pkt(idmsg, lPkt) != NULL)
				{
					lPkt = rim_pkt(idmsg, lPkt);
				}
			} 
			else if( ch=='N' )
			{
				struct listaPKT *list_aux;

				list_aux = NULL;

				ris=recv(monitorfd,(char*)&idmsg,sizeof(uint32_t),0);
				if(ris!=sizeof(uint32_t)) { fprintf(stderr,"(N)recv nack failed: "); exit(9); }

				/* Restituisce il puntatore lista all'elemento interessato */
				list_aux = find_id_pkt(idmsg, lPkt);

				/* Se il pacchetto NACKato è presente nella lista */
				if(list_aux != NULL)
				{
					/* E se la porta da cui è stato inviato il pacchetto è uguale all'attuale da cui s'invia */
					if(list_aux->portaPKT == cfgPorte[index])
					{
						/* Viene cambiata */
						index=(index+1)%numporte;
					}
					/* Aggiorna anche la porta d'invio del pacchetto */
					list_aux->portaPKT = cfgPorte[index];
					
					/* Rispedisce l'esatto pacchetto che è stato NACKato */
					ris=send_udp(monitordatafd, (char*)list_aux->pkt, sizeof(list_aux->pkt) , 1000, "127.0.0.1", cfgPorte[index] );
					if(!(ris))
					{
						fprintf(stderr,"pkt id %u NOT sent\n", list_aux->pkt[0] );
					}
				}
			}

		}
		
		/* Controlla se sono arrivati pacchetti dall'applicazione */
		if( FD_ISSET(appmobilefd,&rdset) )
		{
			lettura_pkt_app();
		}
		
	} /* fine for ;; */
	
/***********************************************************************************************************/

			break;
		case CONN_VELOCE:
				
#ifdef TIPO_CONN
			fprintf(stderr,GREEN "\n*** Attivazione della connessione VELOCE ***\n" DEFAULTCOLOR "\n");
#endif
			
/* *********************************************** VELOCE ************************************************** */

	for(;;)
	{
		do {
			rdset=all;

#ifdef VICDEBUG
			stampa_fd_set("rdset prima",&rdset);
#endif

			ris=select(maxfd+1,&rdset,NULL,NULL,NULL);
		} while( (ris<0) && (errno==EINTR) );
		if(ris<0) {
			perror("select failed: ");
			exit(1);
		}

#ifdef VICDEBUG
		stampa_fd_set("rdset dopo",&rdset);
#endif

		/* Lettura dei pacchetti UDP provenienti dal Monitor */
		if(FD_ISSET(monitordatafd,&rdset))
		{
			lettura_pkt_monitor();
		}

		/* Lettura dei pacchetti TCP (CONF, ACK, NACK) provenienti dal Monitor */
		if( FD_ISSET(monitorfd,&rdset) )
		{
			char ch; int ris;
			uint32_t tmpnumporte;
			uint16_t tmpporte[MAXNUMCONNECTIONS];
			uint32_t idmsg;

			/* ris=recv(monitorfd,buf,65536,MSG_DONTWAIT); */
			ris=recv(monitorfd,&ch,1,0);
			if(ris!=1) { fprintf(stderr,"recv from monitor failed: "); exit(9); }

			if(ch=='C') 
			{
				ris=recv(monitorfd,(char*)&tmpnumporte,sizeof(uint32_t),0);
				if(ris!=sizeof(uint32_t)) { fprintf(stderr,"(C)recv_configurazione failed: "); exit(9); }

				for(i=0;i<tmpnumporte;i++)
				{
 					ris=recv(monitorfd,&(tmpporte[i]),sizeof(uint16_t),0);
					if(ris!=sizeof(uint16_t)) { fprintf(stderr,"(C%d)recv_configurazione failed: ",i); exit(9); }

				}
				
				config_new_porte(cfgPorte, tmpporte);

				setup_new_configurazione(&numporte,porte,&tmpnumporte,tmpporte);

				/* Creazione del pacchetto della configurazione delle porte */
				config_pkt_porte(cfgPKT, numporte);
				
				send_config(cfgPKT, monitordatafd, cfgPorte, numporte);
			} 
			else if( ch=='A' ) 
			{
				ris=recv(monitorfd,(char*)&idmsg,sizeof(uint32_t),0);
				if(ris!=sizeof(uint32_t)) { fprintf(stderr,"(A)recv ack failed: "); exit(9); }

				/* Se arriva un ACK presente nella lista di pacchetti, lo rimuove */
				if(find_id_pkt(idmsg, lPkt) != NULL)
				{
					lPkt = rim_pkt(idmsg, lPkt);
				}
				
				/* Incrementa il contatore degli ACK */
				contACK++;
			} 
			else if( ch=='N' ) 
			{
				struct listaPKT *list_aux;

				list_aux = NULL;

				ris=recv(monitorfd,(char*)&idmsg,sizeof(uint32_t),0);
				if(ris!=sizeof(uint32_t)) { fprintf(stderr,"(N)recv nack failed: "); exit(9); }

				/* Restituisce il puntatore lista all'elemento interessato */
				list_aux = find_id_pkt(idmsg, lPkt);

				/* Se il pacchetto NACKato è presente nella lista */
				if(list_aux != NULL)
				{
					/* Se precedentemente sono arrivati almeno due ACK dietro fila, vuol dire che attualmente il Mobile
					   è connesso sulla porta 'OK', quindi viene data una seconda chance al pacchetto rinviandolo sulla
					   medesima porta, altrimenti si scorre il vettore di porte dato che due NACK sulla stessa porta
					   indicano il cambiamento in 'LOSS' */

					if(contACK < NUM_CONTACK)
					{
						if(list_aux->portaPKT == cfgPorte[index])
						{
							index=(index+1)%numporte;
						}
					}
					else
					{
						contACK = 0;
					}

					/* Aggiorna anche la porta d'invio del pacchetto */
					list_aux->portaPKT = cfgPorte[index];
					
					/* Rispedisce l'esatto pacchetto che è stato NACKato */
					ris=send_udp(monitordatafd, (char*)list_aux->pkt, sizeof(list_aux->pkt) , 1000, "127.0.0.1", cfgPorte[index] );
					if(!(ris))
					{
						fprintf(stderr,"pkt id %u NOT sent\n", list_aux->pkt[0] );
					}
				}
			}

		}
		
		/* Controlla se sono arrivati pacchetti dall'applicazione */
		if( FD_ISSET(appmobilefd,&rdset) )
		{
			lettura_pkt_app();
		}


	} /* fine for ;; */
	
/***********************************************************************************************************/
			
			break;
		case CONN_LENTA:
						
#ifdef TIPO_CONN
			fprintf(stdout,ORANGE "\n*** Attivazione della connessione LENTA ***\n" DEFAULTCOLOR "\n");
#endif
			
/* *********************************************** LENTA ************************************************** */

	for(;;)
	{
		do {
			rdset=all;

#ifdef VICDEBUG
			stampa_fd_set("rdset prima",&rdset);
#endif

			ris=select(maxfd+1,&rdset,NULL,NULL,NULL);
		} while( (ris<0) && (errno==EINTR) );
		if(ris<0) {
			perror("select failed: ");
			exit(1);
		}

#ifdef VICDEBUG
		stampa_fd_set("rdset dopo",&rdset);
#endif

		/* Lettura dei pacchetti UDP provenienti dal Monitor */
		if(FD_ISSET(monitordatafd,&rdset))
		{
			lettura_pkt_monitor();
		}

		/* Lettura dei pacchetti TCP (CONF, ACK, NACK) provenienti dal Monitor */
		if( FD_ISSET(monitorfd,&rdset) )
		{
			char ch; int ris;
			uint32_t tmpnumporte;
			uint16_t tmpporte[MAXNUMCONNECTIONS];
			uint32_t idmsg;

			/* ris=recv(monitorfd,buf,65536,MSG_DONTWAIT); */
			ris=recv(monitorfd,&ch,1,0);
			if(ris!=1) { fprintf(stderr,"recv from monitor failed: "); exit(9); }

			if(ch=='C') 
			{	
				ris=recv(monitorfd,(char*)&tmpnumporte,sizeof(uint32_t),0);
				if(ris!=sizeof(uint32_t)) { fprintf(stderr,"(C)recv_configurazione failed: "); exit(9); }

				for(i=0;i<tmpnumporte;i++)
				{
 					ris=recv(monitorfd,&(tmpporte[i]),sizeof(uint16_t),0);
					if(ris!=sizeof(uint16_t)) { fprintf(stderr,"(C%d)recv_configurazione failed: ",i); exit(9); }

				}
				
				config_new_porte(cfgPorte, tmpporte);

				setup_new_configurazione(&numporte,porte,&tmpnumporte,tmpporte);

				/* Creazione del pacchetto della configurazione delle porte */
				config_pkt_porte(cfgPKT, numporte);
				
				send_config(cfgPKT, monitordatafd, cfgPorte, numporte);
			} 
			else if( ch=='A' ) 
			{
				ris=recv(monitorfd,(char*)&idmsg,sizeof(uint32_t),0);
				if(ris!=sizeof(uint32_t)) { fprintf(stderr,"(A)recv ack failed: "); exit(9); }

				/* Se arriva un ACK presente nella lista di pacchetti, lo rimuove */
				if(find_id_pkt(idmsg, lPkt) != NULL)
				{
					lPkt = rim_pkt(idmsg, lPkt);
				}
			} 
			else if( ch=='N' ) 
			{
				struct listaPKT *list_aux;

				list_aux = NULL;

				ris=recv(monitorfd,(char*)&idmsg,sizeof(uint32_t),0);
				if(ris!=sizeof(uint32_t)) { fprintf(stderr,"(N)recv nack failed: "); exit(9); }

				/* Restituisce il puntatore lista all'elemento interessato */
				list_aux = find_id_pkt(idmsg, lPkt);

				/* Se il pacchetto NACKato è presente nella lista */
				if(list_aux != NULL)
				{
					/* Se non sono arrivati dei NACK precedentemente, viene data la seconda chance all'attuale pacchetto
					   NACKato, altrimenti si scorre il vettore di porte */
					if(contACK > 0)
					{
						if(list_aux->portaPKT == cfgPorte[index])
						{
							index=(index+1)%numporte;
						}
						contACK = 0;
					}
					/* Aggiorna anche la porta d'invio del pacchetto */
					list_aux->portaPKT = cfgPorte[index];
					
					/* Rispedisce l'esatto pacchetto che è stato NACKato */
					ris=send_udp(monitordatafd, (char*)list_aux->pkt, sizeof(list_aux->pkt) , 1000, "127.0.0.1", cfgPorte[index] );
					if(!(ris))
					{
						fprintf(stderr,"pkt id %u NOT sent\n", list_aux->pkt[0] );
					}
					
					contACK++;
				}
			}

		}
		
		/* Controlla se sono arrivati pacchetti dall'applicazione */
		if( FD_ISSET(appmobilefd,&rdset) )
		{
			lettura_pkt_app();
		}


	} /* fine for ;; */
	
/***********************************************************************************************************/
			
			break;
		default:
			fprintf(stderr,"Errore durante la configurazione del tipo di connessione.\n");
			exit(1);
			break;
	}
	
	close(monitorfd);
	return(0);
}
Ejemplo n.º 2
0
int main (int argc, char *argv[])
{
    	int tuttoOK=1;
    	short int local_port_number;
    	int listenfd[3], connectedfd[3], socketfd, ris, i, nwrite, nread, n;
    	struct sockaddr_in Cli;
	int *intptr;
	pthread_t thid[10];
	/*pthread_attr_t attr;*/
	unsigned int len;
	char buflettura[LENVETLETTURA];
	char bufscrittura[LENVETSCRITTURA];
	int sum, sumlettura;

	if    ( (sizeof(int)!=sizeof(long int)) ||  (sizeof(int)!=4)  )
	{
		printf ("dimensione di int e/o long int != 4  -> TERMINO\n");
		fflush(stdout);
		exit(1);
	}

    	if (argc != 2)
	{
		printf ("necessario 1 parametro\n");
		usage ();
		exit (1);
    	}
    	else
    	{
		local_port_number = atoi (argv[1]);
    	}
	
	init_random();

	if( ! Init_TCP_Session_Module(NULL) )
	{
		printf ("Init_TCP_Session_Module() failed\n");
		fflush(stdout);
		exit(1);
	}

	for(i=0;i<2;i++)
	{
		ris=TCPS_setup_socket_listening( listenfd+i, local_port_number+i);
		if (!ris)
		{	
			printf ("setup_socket_listening() failed\n");
			exit(1);
		}
	}
	ris=TCP_setup_socket_listening( listenfd+2, local_port_number+2);
	if (!ris)
	{	
		printf ("setup_socket_listening() failed\n");
		exit(1);
	}

	/*sleep(50);*/

	ris= TCP_setup_connection(&socketfd, "127.0.0.1", local_port_number+2);
	if (!ris)  {
		printf ("impossibile connettersi al server: TERMINO!!\n" );
		fflush(stdout);
		exit(1);
	}

	/*
	pthread_attr_init(&attr);
	pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
	*/

	for(i=0;i<3;i++)
	{
		intptr=malloc(sizeof(int));
		if(intptr==NULL) { perror("malloc failed: "); fflush(stderr); exit(1); }

		/* wait for connection request */
		memset (&Cli, 0, sizeof (Cli));
		len = sizeof (Cli);
		for(;;)
		{
			printf ("Accept()\n");
			*intptr = Accept (listenfd[i], (struct sockaddr *) &Cli, &len);
			if (*intptr == SOCKET_ERROR)
			{
				if(errno==EINTR) continue;
				else
				{
					printf ("Accept() failed, Err: %d \"%s\"\n", errno,
					strerror (errno));
					exit (1);
				}
			}
			else
			{
				connectedfd[i]=*intptr;
				/*printf("fd_accept server %d \n", connectedfd[i]);*/
				/*ris=pthread_create(&(thid[i]), &attr, (ptr_thread_routine) &thread_For_Read_Write, (void *) intptr );*/
				ris=pthread_create(&(thid[i]), NULL, (ptr_thread_routine) &thread_For_Read_Write, (void *) intptr );
				if(ris)
				{
					/*
					Close(*intptr);
					Close(listenfd[i]);
					free(intptr);
					*/
					fprintf (stdout, "pthread_create( For_Read_Write ) failed, Err: %d \"%s\"\n", errno,strerror(errno));
					exit(2);
				}
				else
				{
					printf ("pthread_create succeed\n");
					break;
				}
			} /* fine creazione threads */
		} /* fine for(;;) */
	} /* for(i=0;i<3;i++) */

	for(i=0;i<2;i++)
	{
		ris=pthread_join( thid[i] , (void*) &intptr );
		if(ris!=0){
			printf("pthread_join( %d) failed: error=%d\n", i, ris );
			exit(-1);
		}
		else
		{
			if(intptr==NULL)
			{
				printf("pthread failed: malloc error\n");
				fflush(stdout);
				tuttoOK=0;
				exit(-1);
			}
			else if(*intptr==0)
			{
				printf("pthread failed: network error\n");
				fflush(stdout);
				tuttoOK=0;
				exit(-1);
			}
			else
				printf("pthread ok\n");
			fflush(stdout);
		}
	}

	/* parte client del socket tcp normale */
	nread=sizeof(int);
	/*printf("nread= %d", nread);*/
	printf ("Readn() sum \n");
	fflush (stdout);

	n = Readn (socketfd, (char*) &(sum), nread);
	if (n != nread)
	{
		printf ("Readn() sum failed \n");
		fflush(stdout);
		return (0);
	}
	sum=ntohl(sum);

	/* scrittura sul socket tcp normale */
	nwrite = LENVETSCRITTURA;
	printf ("Writen()\n");
	fflush (stdout);

	n = Writen (socketfd, bufscrittura, nwrite );
	if (n != nwrite)
	{
		printf ("Writen() failed \n");
		fflush(stdout);
		return (0);
	}
	/* lettura dal socket tcp normale*/
	nread=LENVETLETTURA;
	n = Readn (socketfd, buflettura, nread);
	if (n != nread)
	{
		printf ("Readn() main failed \n");
		fflush(stdout);
		return (0);
	}
	sumlettura=sommavet(buflettura,LENVETLETTURA);
	printf("somma spedita %d  somma calcolata %d\n", sum, sumlettura );
	fflush (stdout);
	/*
	stampavet(buflettura,LENVETLETTURA);
	fflush (stdout);
	*/
	if(sumlettura!=sum)
	{
		printf ("\033[33;35;1m somma del tcp errata: errore in trasmissione dati\n \033[0m ");
		fflush(stdout);
		return (0);
	}

	/* fine parte client del socket tcp normale */

	/* attesa thread che ha gestito il server con il socket tcp normale */
	ris=pthread_join( thid[2] , (void*) &intptr );
	if(ris!=0){
		printf("pthread_join( 2) failed: error=%d\n", ris );
		exit(-1);
	}
	else
	{
		if(intptr==NULL)
		{
			printf("pthread failed: malloc error\n");
			tuttoOK=0;
		}
		else if(*intptr==0)
		{
			printf("pthread failed: network error\n");
			tuttoOK=0;
		}
		else
			printf("pthread ok\n");
		fflush(stdout);
	}

	for(i=0;i<3;i++) {
		Close (connectedfd[i]);
		Close (listenfd[i]);
	}
	Close (socketfd);

    	printf ("Fine main\n");
	if(tuttoOK==0)
	{
    		printf ("\033[33;35;1m C'e' stato un errore di comunicazione\n \033[0m \n");
		fflush(stdout);
		exit(1);
	}
	if( ! Close_TCP_Session_Module(NULL) )
	{
		printf ("\033[33;35;1m Close_TCP_Session_Module() failed\n \033[0m ");
		fflush(stdout);
		exit(1);
	}
	
    	printf ("Tutto OK\n");
	fflush(stdout);
	return (0);
}
Ejemplo n.º 3
0
int main (int argc, char *argv[])
{

    short int local_port_number;
    int listenfd[2], connectedfd[3], to_close[3], status[3];
	int Vnwritten[3], Vnread[3];
	int socketfd, nreadTCP, nwriteTCP, statusTCP=0;
    struct sockaddr_in Cli;
	int ris, i, nwrite, nread, n;
	int noattesa;

	unsigned int len;
	char minibuf[3][10], minibufclient[10];
	char *bufclient;
	char *bufsend[3], *bufrecv[3];
	fd_set fdR, fdW, temp_fdR, temp_fdW;
	struct timeval tv;
	int myerrno, maxfd;
	int nconnected=0, num;

    if (argc != 2)
    {
		printf ("necessario 1 parametro\n");
		usage ();
		exit (1);
    }
    else
    {
		local_port_number = atoi (argv[1]);
    }

	bufclient=malloc(MAXSIZE);
	if(bufclient==NULL) { perror("malloc failed: "); exit(1);}
	for(i=0;i<3;i++)
	{
		bufsend[i]=malloc(MAXSIZE);
		if(bufsend[i]==NULL) { perror("malloc failed: "); exit(1);}
		bufrecv[i]=calloc(1,MAXSIZE);
		if(bufrecv[i]==NULL) { perror("malloc failed: "); exit(1);}
	}
	init_random();
	for(i=0;i<3;i++)
		inizializza(bufsend[i],MAXSIZE);
	
	if( ! Init_TCP_Session_Module(NULL) )
	{
		printf ("Init_TCP_Session_Module() failed\n");
		fflush(stdout);
		exit(1);
	}

	ris=TCPS_setup_socket_listening( &(listenfd[0]), local_port_number);
	if (!ris)
	{	
		printf ("setup_socket_listening() failed\n");
		exit(1);
	}

	ris=TCP_setup_socket_listening( &(listenfd[1]), local_port_number+1);
	if (!ris)
	{	
		printf ("setup_socket_listening() failed\n");
		exit(1);
	}

	ris= TCP_setup_connection(&socketfd, "127.0.0.1", local_port_number+1);
	if (!ris)  {
		printf ("impossibile connettersi al server: TERMINO!!\n" );
		fflush(stdout);
		exit(1);
	}
#ifdef VERBOSE
	printf("socket TCP client %d\n", socketfd );
	fflush(stdout);
#endif

	FD_ZERO(&fdR);
	FD_ZERO(&fdW);
	FD_SET(listenfd[0],&fdR);
	FD_SET(listenfd[1],&fdR);
	FD_SET(socketfd,&fdW);
	if(socketfd>listenfd[0])	maxfd=socketfd;
	else				maxfd=listenfd[0];
	if(listenfd[1]>maxfd)		maxfd=listenfd[1];

#ifdef VERBOSE
	printf("socket listening: %d %d\n", listenfd[0], listenfd[1] );
	fflush(stdout);
#endif

	noattesa=NUMCICLITRAATTESA;

	do
	{
		if(noattesa==0)
		{
#ifdef VERBOSE
			printf("sleep(1) \n");
			fflush(stdout);
#endif
			sleep(1);
			noattesa=NUMCICLITRAATTESA;
		}
		else
		{
#ifdef VERBOSE
			printf("no sleep() \n");
			fflush(stdout);
#endif
			noattesa--;
		}

		do {
			temp_fdR=fdR;
			temp_fdW=fdW;
			tv.tv_sec=20;
			tv.tv_usec=0;

			/*
			printf("Select ...  ");
			fflush(stdout);
            		*/

			ris=Select(maxfd+1, &temp_fdR, &temp_fdW, NULL, &tv );
			myerrno=errno;

			/*
       		printf(" fine Select\n");
			fflush(stdout);
            		*/

		} while( (ris<0)&&(myerrno==EINTR) );

		if(ris==0)
		{
			printf("Select timeout: repeat\n");
			fflush(stdout);
		}
		else if(ris<0)
		{
			perror("Select() failed: ");
			printf("TERMINO !!!!!\n");
			fflush(stdout);
			exit(1);
		}
		else
		{
			/* ris>0 */

			/* accetto al massimo due "connessioni TCP con Sessione" ed una "normale" */
			for(i=0;i<2;i++)
			{
				if( listenfd[i] >= 0 )
				{
					if( FD_ISSET(listenfd[i], &temp_fdR) )
					{
						len=sizeof(Cli);
						ris=Accept (listenfd[i], (struct sockaddr *) &Cli, &len);
						myerrno=errno;
						if(ris<0)
						{
							if(myerrno!=EINTR)
							{
								printf ("Accept(%d) failed, Err: %d \"%s\"\nTERMINO!!!",
											listenfd[i], myerrno, strerror (myerrno));
								exit (1);
							}
						}
						else
						{
							connectedfd[nconnected]=ris;
							to_close[nconnected]=ris;
							status[nconnected]=0; 
							FD_SET(connectedfd[nconnected],&fdR);
							if(connectedfd[nconnected]>maxfd)	maxfd=connectedfd[nconnected];

							printf("Accettata connessione %d dal socket listening %d\n",
									connectedfd[nconnected], listenfd[i] );

							nconnected++;
							if((nconnected==3)||(i==1))
							{
								FD_CLR(listenfd[i], &temp_fdR);
								FD_CLR(listenfd[i], &fdR);
								/* attenzione qui, a chi deve gestire le riconnessioni */
								printf("Chiuso socket listening %d\n", listenfd[i] );

								Close(listenfd[i]);
								listenfd[i]=-1;
	
							}
		
						}
					}
				}
			}

			/* le connessioni "lato server" */
			for(i=0;i<nconnected;i++)
			{
				if( connectedfd[i] >= 0 )
				{
					if( FD_ISSET(connectedfd[i], &temp_fdR) )
					{
						/* disponibile in lettura */
						ris=AvailableBytes(connectedfd[i],&num);
						if(ris==0)
						{
							printf("AvailableBytes from server %d failed\nTERMINO!!!", connectedfd[i]);
							fflush(stdout);
							exit(1);
						}
						if(num==0)
						{
							/* nessun byte disponibile -> e' stata chiusa la connessione
							 Close(connectedfd[i]);
               				*/
							
							FD_CLR(connectedfd[i], &fdR);
							FD_CLR(connectedfd[i], &fdW);
							printf("Connessione %d Chiusa inaspettatamente\nTERMINO!!!!\n", connectedfd[i]);
							fflush(stdout);
							connectedfd[i]=-1;
							exit(1);
						}
						else
						{
							/* qualcosa da leggere */
							if(status[i]==0)
							{
								/* leggo 10 bytes, in modo bloccante */
								nread=10;
								n = Readn (connectedfd[i], minibuf[i], nread);
								if (n != nread)
								{
									printf ("Readn() failed \nTermino\n");
									fflush(stdout);
									exit(1);
								}
								else
								{
									FD_SET(connectedfd[i],&fdW);
									Vnwritten[i]=0;
									status[i]=1;
									Vnread[i]=0;
#ifdef VERBOSE
									printf("Read %d bytes using %d\n", n, connectedfd[i] );
									fflush(stdout);
#endif
								}
							}
							else
							{
								/* status[i]==1   seconda lettura */
								n = Read (connectedfd[i], bufrecv[i]+(Vnread[i]), MAXSIZE-Vnread[i]>STEPSIZE?STEPSIZE:MAXSIZE-Vnread[i] );
								myerrno=errno;
								if(n<0)
								{
									if(myerrno!=EINTR)
									{
										printf ("Read() failed \nTermino\n");
										fflush(stdout);
										exit(1);
									}
								}
								else
								{
#ifdef VERBOSE
									printf("read %d bytes from connection %d\n", n, connectedfd[i] );
									fflush(stdout);
#endif
									Vnread[i]+=n;

									if(Vnread[i]==MAXSIZE)
									{

										printf("La Connessione %d ha finito correttamente il proprio lavoro\n", connectedfd[i] );
										fflush(stdout);

										FD_CLR(connectedfd[i], &fdR);
										FD_CLR(connectedfd[i], &temp_fdR);
										FD_CLR(connectedfd[i], &fdW);
										FD_CLR(connectedfd[i], &temp_fdW);
										connectedfd[i]=-1;
									}
								}
							}
						}
					}
				}
				if( connectedfd[i] >= 0 )
				{
					if( FD_ISSET(connectedfd[i], &temp_fdW) )
					{
						nwrite=MAXSIZE;
						do {
							n = Send (	connectedfd[i], bufsend[i]+(Vnwritten[i]),
										nwrite-Vnwritten[i]>STEPSIZE?STEPSIZE:nwrite-Vnwritten[i],
										MSG_NOSIGNAL|MSG_DONTWAIT
										);
							myerrno=errno;
						} while ( (n<0)&&(myerrno==EINTR) );
						if ( n < 0 )
						{
							printf ("Send() failed \nTermino\n");
							fflush(stdout);
							exit(1);
						}
						else
						{
#ifdef VERBOSE
							printf("Sent %d bytes using server %d\n", n, connectedfd[i]);
							fflush(stdout);
#endif
							Vnwritten[i]+=n;
							if(Vnwritten[i]==nwrite)
							{
#ifdef VERBOSE
								printf("Una Connessione %d ha finito di inviare\n", connectedfd[i] );
								fflush(stdout);
#endif
								FD_CLR(connectedfd[i], &fdW);
								FD_CLR(connectedfd[i], &temp_fdW);

							}
						}
					}
				}
			}

			if(socketfd>=0)  /* funge da client locale, deve scrivere poi leggere poi scrivere */
			{
				if( FD_ISSET(socketfd, &temp_fdW) )
				{
					if(statusTCP==0)
					{
						nwrite = 10;
#ifdef VERBOSE
						printf ("Writen() %d bytes su TCP client locale %d\n", nwrite, socketfd );
						fflush (stdout);
#endif
						n = Writen (socketfd, minibufclient, nwrite );
						if (n != nwrite)
						{
							printf ("Writen() using %d TCP client failed \nTERMINO\n", socketfd);
							fflush(stdout);
							exit(2);
						}
						/* non devo piu' spedire */
						FD_CLR(socketfd, &fdW);
						FD_CLR(socketfd, &temp_fdW);
						/* devo ricevere */
						FD_SET(socketfd, &fdR);
						nreadTCP=0;

#ifdef VERBOSE
						printf ("fine Writen() %d bytes su TCP client locale %d \n", n, socketfd );
						fflush (stdout);
#endif
					}
					else  /* statusTCP==1 */
					{
						n = Send (socketfd, bufclient+nwriteTCP, MAXSIZE-nwriteTCP, MSG_NOSIGNAL|MSG_DONTWAIT );
						myerrno=errno;
						if ( n < 0 )
						{
							if(myerrno!=EINTR)
							{
								printf ("Send() using %d TCP client failed \nTermino\n",socketfd);
								fflush(stdout);
								exit(1);
							}
						}
						else if ( n == 0 )
						{
							printf ("Send() using %d TCP client failed: Sent 0 bytes: strano\nTermino\n", socketfd);
							fflush(stdout);
							exit(1);
						}
						else /* n>0 */
						{
#ifdef VERBOSE
							printf("Sent %d bytes using %d TCP client\n", n, socketfd );
							fflush(stdout);
#endif
							nwriteTCP+=n;
							if(nwriteTCP==MAXSIZE)
							{
								printf("la Connessione %d TCP client ha finito il proprio lavoro\n", socketfd );
								fflush(stdout);

								FD_CLR(socketfd, &fdR);
								FD_CLR(socketfd, &fdW);
								FD_CLR(socketfd, &temp_fdR);
								FD_CLR(socketfd, &temp_fdW);

							}
						}

					}
				}
			}

			/* la connessione TCP "client" dopo avere spedito vuole ricevere */
			if(socketfd>=0)
			{
				if( FD_ISSET(socketfd, &temp_fdR) )
				{
					/* disponibile in lettura */
					ris=AvailableBytes(socketfd,&num);
					if(ris==0)
					{
						printf("AvailableBytes from TCP client %d failed\nTERMINO!!!", socketfd );
						fflush(stdout);
						exit(1);
					}
					if(num==0)
					{
						/* nessun byte disponibile -> e' stata chiusa la connessione */
						Close(socketfd);
						FD_CLR(socketfd, &fdR);
						FD_CLR(socketfd, &fdW);
						FD_CLR(socketfd, &temp_fdR);
						FD_CLR(socketfd, &temp_fdW);
						printf("Connessione socketfd %d Chiusa troppo presto\nTERMINO!!!", socketfd );
						fflush(stdout);
						socketfd=-1;
						exit(1);
					}
					else
					{
						/* qualcosa da leggere, lettura non bloccante */
						do {
							n = Read (socketfd, bufclient+nreadTCP, MAXSIZE-nreadTCP );
							myerrno=errno;
						} while ( (n<0)&&(myerrno==EINTR) );
						if ( n < 0 )
						{
							printf ("Read() failed \nTermino\n");
							fflush(stdout);
							exit(1);
						}
						else
						{
							nreadTCP+=n;

#ifdef VERBOSE
							printf("read %d bytes from connection TCP client %d\n", n, socketfd );
							fflush(stdout);
#endif
							if(nreadTCP==MAXSIZE)
							{
#ifdef VERBOSE
								printf("La Connessione TCP client ha finito di leggere\n");
								fflush(stdout);
#endif
								/* abilito anche la scrittura */
								FD_SET(socketfd, &fdW);
								statusTCP=1;
								nwriteTCP=0;
								FD_CLR(socketfd, &temp_fdR);
								FD_CLR(socketfd, &temp_fdW);

							}
						}
					}
				}
			}



		}  /* fine ris>0  */

	}  while( not_empty( maxfd, &fdR,&fdW) );
	
#ifdef VERBOSE
    printf ("Fine main\n");
	fflush(stdout);
#endif
    /* printf ("sleep 10 secs\n");
	fflush(stdout);
	sleep(10);
    */

    printf ("Close varie\n");
	fflush(stdout);

	if( Close(socketfd) != 0 )
		perror("Close failed\n");
	for(i=0;i<nconnected;i++)
		if(Close(to_close[i]) != 0 )
			perror("Close failed\n");

    printf ("call to CloseWait_TCP_Session_Module ...\n");
    fflush(stdout);
    n=CloseWait_TCP_Session_Module(NULL,NULL);
    switch(n) {
        case -1: printf ("CloseWait_TCP_Session_Module returns %d: error\n", n); break;
        case 0:  printf ("CloseWait_TCP_Session_Module returns %d: timeout expired\n", n); break;
        case 1:  printf ("CloseWait_TCP_Session_Module returns %d: ok\n", n); break;
        default: printf ("CloseWait_TCP_Session_Module returns %d: unknown error code\n", n); break;
    }
    fflush(stdout);

	/* controllo quel che ho ricevuto */
	for(i=0;i<3;i++)
	{
		unsigned int j;

		for(j=0;j<MAXSIZE;j++) 
			if(bufrecv[i][j] != bufsend[i][j])
			{
			printf ("\033[33;35;1m bufrecv[%d][%d] %d DIVERSO da bufsend[%d][%d] %d  : errore in trasmissione dati\n \033[0m ",
					i,j, bufrecv[i][j], i,j, bufsend[i][j]  );
			fflush(stdout);
			return (0);
			}
	}
    return (0);
}