Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 13
  1. #1

    [C] comunicazione client-server con fork

    Ciao a tutti,
    ho un problema con un programma che sto sviluppando riguardante la comunicazione tra i processi figli.
    ho estratto una parte ridotta del programma (dato che il mio problema è strettamente di comunicazione) per farvi vedere un esempio in cui il client deve semplicemente ottenere la lista dei file presenti sul server.
    per necessità questa operazione va fatta gestire da child mentre i rispettivi parent tornano rispettivamente uno in ascolto e l'altro nel menù.

    in due parole, a livello comunicativo:
    -il client crea il socket del processo padre, seleziona l'azione e la invia al processo padre del server.
    -il processo padre del server, ricevuta l'azione crea la socket con una porta random libera che il futuro figlio utilizzerà inviandone il numero al client.
    -il client creerà a sua volta la socket del figlio associata alla porta appena ricevuta.
    -ambo i lati creano i figli, chiudono le socket del padre e svolgono lo scambio dei dati mentre i padri tornano ai loro compiti principali (il server in attesa, il client nel menu).

    il codice non è pulitissimo e ha parecchie stampe di controllo perchè ho fatto molte prove ma non riesco proprio ad uscirne...

    posto il codice del client qui mentre il server e l'header nel prossimo messaggio (problemi col numero massimo di caratteri)

    codice:
    #include "header.h"
    
    int psockfd, csockfd, scritti, letti, num_pack, mod_pack, i;
    unsigned int paddrlen, caddrlen;
    char azione, *ultimo, *ultimo_lista;
    char nomefile[MAXLINE], recvline[MAXLINE + 1], list_file[MAXLINE] =  "Lista file server";
    int ricporta;
    struct sockaddr_in psrvrddrss;
    struct sockaddr_in csrvrddrss;
    
    struct Pacchetto 
    {
    	int num_seq;
    	char bit_string[MAXLINE];
    } ricevuto;
    
    DIR *dp;
    FILE *filep, *fopen(), *list_fd;
    
    int main (int argc, char** argv)
    {
    	//Controllo numero argomenti
    	if (argc != 2)
    	{
    		perror("Indirizzo del server ip mancante.\n");
    		exit(1);
    	}
    	
    	//Creazione del socket del processo padre
    	if ((psockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
    	{
    		perror("Errore nella creazione del socket.\n");
    		exit(1);
    	}
    	
    	paddrlen = sizeof(psrvrddrss);
    	//Svuotamento srvraddrss
    	memset((void *)&psrvrddrss, 0, sizeof(psrvrddrss));
    	
    	//Assegnazione del tipo di indirizzo
    	psrvrddrss.sin_family = AF_INET;
    	
    	//Assegnazione porta del servar
    	psrvrddrss.sin_port = htons (SERV_PORT);
    	
    	/*Assegnazione dell'indirizzo del server tramite riga di comando
    	 l'indirizzo è una stringa e va convertito in network byte order*/
    	if (inet_pton(AF_INET, argv[1], &psrvrddrss.sin_addr) <= 0)
    	{
    		fprintf(stderr, "Errore in inet_pton per %s.\n", argv[1]);
    		exit(1);
    	}
    	
    	for ( ; ; )
    	{
    		//Menu di scelta azione
    		printf("Digitare l per ottenere una lista dei file disponibili,\n");
    		scanf("%c", &azione);
    		getchar();
    		
    		//Trasmissione al server l'azione scelta dall'utente
    		if ((scritti = sendto(psockfd, &azione, 1, 0, (struct sockaddr *)&psrvrddrss, sizeof(psrvrddrss))) < 0)
    		{
    			perror("Errore nella scrittura.\n");
    			exit(1);
    		}
    		
    		//Ricezione numero di porta del server
    		if(letti = recvfrom(psockfd, (int*)&ricporta, 4, 0, (struct sockaddr *)&psrvrddrss, &paddrlen) < 0)
    		{
    			perror("Errore in lettura. \n");
    			exit(1);
    		}
    		
    		//Creazione del socket del processo figlio
    		if ((csockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
    		{
    			perror("Errore nella creazione del socket.\n");
    			exit(1);
    		}
    		
    		caddrlen = sizeof(csrvrddrss);
    		//Svuotamento srvraddrss
    		memset((void *)&csrvrddrss, 0, sizeof(csrvrddrss));
    		
    		//Assegnazione del tipo di indirizzo
    		csrvrddrss.sin_family = AF_INET;
    		
    		//Assegnazione porta del servar
    		csrvrddrss.sin_port = ricporta;
    		
    		/*Assegnazione dell'indirizzo del server tramite riga di comando
    		 l'indirizzo è una stringa e va convertito in network byte order*/
    		if (inet_pton(AF_INET, argv[1], &csrvrddrss.sin_addr) <= 0)
    		{
    			fprintf(stderr, "Errore in inet_pton per %s.\n", argv[1]);
    			exit(1);
    		}
    		
    		//Creazione processo figlio
    		pid_t pid = fork();
    		
    		//Controllo di errore pid
    		if(pid < 0) printf("Errore nella creazione del processo figlio.\n");
    		
    		//Codice processo figlio
    		if(pid == 0)
    		{
    			printf("Creato il figlio: %d.\n", getpid());
    			//Chiusura socket del padre
    			close(psockfd);
    			
    			//Menu di scelta
    			switch (azione)
    			{
    					//Lista file
    				case 'l': case 'L':
    					
    					printf("Richiedo la lista dei file disponibili...\n");
    					
    					//Apertura del file in scrittura, binario, se il file non esiste viene creato
    					list_fd = fopen(list_file, "w+b");
    					
    					
    					/*Ricezione del numero di pacchetti da ricevere dal server*/
    					if(letti = recvfrom(csockfd, (int*)&num_pack, 4, 0, (struct sockaddr*)&csrvrddrss, &caddrlen) < 0)
    					{
    						perror("Errore in lettura.\n");
    						exit(1);
    					}		
    					
    					//Ricezione delle dimensioni dell'ultimo pacchetto
    					if(letti = recvfrom(csockfd, (int*)&mod_pack, 4, 0, (struct sockaddr*)&csrvrddrss, &caddrlen) < 0)
    					{
    						perror("Errore in lettura.\n");
    						exit(1);
    					}
    					
    					if(mod_pack > 0)
    					{
    						//Stampe di controllo
    						printf("Il numero di pacchetti da ricevere è: %d.\n", num_pack);
    						printf("La dimensione dell'ultimo pacchetto è: %d.\n", mod_pack);
    					}
    					else
    					{
    						printf("Il numero di pacchetti da ricevere è: %d.\n", num_pack);
    						mod_pack = MAXLINE;	
    					}
    					
    					//Azzeramento della memoria contenente i campi della struttura
    					memset((void *)&ricevuto, 0, sizeof(ricevuto));
    					
    					//Ricezione pacchetti e copia nel file, tranne l'ultimo
    					for (i=0; i < num_pack - 1; i++)
    					{
    						
    						printf("Sono entrato nel ciclo.\n");
    						
    						if (letti = recvfrom(csockfd, (void *)&ricevuto, sizeof(ricevuto), 0, (struct sockaddr *)&csrvrddrss, &caddrlen) != sizeof(ricevuto))
    						{
    							perror("Errore in lettura.\n");
    							exit(1);
    						}
    						
    						printf("Ho ricevuto il pacchetto.\n");
    						//Scrittura del pacchetto nel file
    						fwrite(ricevuto.bit_string, (MAXLINE*sizeof(char)), 1, list_fd);
    						printf(" %d / %d pacchetti ricevuti | Numero di sequenza pacchetto: %d.\n", i+1, num_pack, ricevuto.num_seq); //Una parte della stampa è di controllo
    						
    						//Pulitura dei buffer input
    						fflush(stdin);
    					}
    					
    					printf("Dopo il ciclo.\n");
    					
    					//Allocazione di memoria per l'ultimo pacchetto
    					ultimo_lista = (char*) malloc(mod_pack);
    					
    					//Ricezione dell'ultimo pacchetto
    					if(letti = recvfrom(csockfd, ultimo_lista, mod_pack, 0, (struct sockaddr*)&csrvrddrss, &caddrlen) < 0)
    					{
    						perror("Errore in lettura.\n");
    						exit(1);
    					}
    					
    					fwrite(ultimo_lista, (mod_pack), 1, list_fd);
    					printf(" %d / %d pacchetti ricevuti. Numero di sequenza: %d.\n", i+1, num_pack, ricevuto.num_seq + 1);
    					
    					fclose(list_fd);
    					printf("Lista ricevuta con successo.\n");
    					fflush(stdout);
    					break;
    					
    					//Exit
    					case 'e' : case 'E':
    					printf("Chiusura programma.\n");
    					break;
    					default:
    					printf("Il comando digitato è errato.\n");
    			}
    			close(csockfd);
    			exit(EXIT_SUCCESS);
    		}
    		//Codice processo padre
    		else
    		{
    			//Chiusura socket del figlio
    			close(csockfd);
    			
    			//Eliminazione degli zombie
    			waitpid(-1, NULL, WNOHANG);
    			
    			//Caso EXIT
    			if(azione == 'e' || azione == 'E') return(0);
    		}
    	}
    	exit(0);									
    }

  2. #2
    ecco il server:
    codice:
    #include "header.h"
    
    int psockfd, csockfd, letti, scritti, num_pack, mod_pack, len, i;
    unsigned int paddrlen, caddrlen;
    char azione, *ultimo, *ultimo_lista;
    char nomefile[MAXLINE + 1], directory[MAXLINE], errore[MAXLINE] = "Il file cercato non esiste.\n", approvato[MAXLINE] = "Il file cercato esiste.\n", lista_file[MAXLINE] = "Lista file server";
    DIR *dp;
    FILE *filep, *fopen(), *list_fd;
    struct sockaddr_in temp;
    struct dirent *dir_p;
    struct sockaddr_in pclntddrss;
    struct sockaddr_in cclntddrss;
    struct Pacchetto
    {
    	int num_seq;
    	char bit_string[MAXLINE];
    } inviato;
    
    int main()
    {
    	//Creazione del socket del processo padre
    	if((psockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
    	{
    		perror("Errore nella creazione del socket.\n");
    		exit(1);
    	}
    	
    	//Azzeramento dello spazio di memoria con l'indirizzo della variabile clntddrss
    	memset((void *)&pclntddrss, 0, sizeof(pclntddrss));
    	
    	//Assegnazione del tipo di indirizzo
    	pclntddrss.sin_family = AF_INET;
    	
    	//Connessioni accettate su qualunque interfaccia di rete
    	pclntddrss.sin_addr.s_addr = htonl(INADDR_ANY);
    	
    	//Assegnazione del numero di porta
    	pclntddrss.sin_port = htons(SERV_PORT);
    	
    	//Assegnazione dell'indirizzo al socket
    	/*nella prima parte struct sockaddr... fino alla virgola, cambia il tipo della variabile clntddrss*/
    	if ((bind(psockfd, (struct sockaddr *)&pclntddrss, sizeof(pclntddrss))) < 0)
    	{
    		perror("Errore in bind.\n");
    		exit(1);
    	}
    	printf("Il padre ha la porta: %d.\n", ntohs(pclntddrss.sin_port));
    	
    	for ( ; ; )
    	{
    		printf("In attesa dell'azione da svolgere...\n");
    		
    		paddrlen = sizeof(pclntddrss);
    		//Controllo del tipo di richiesta del client
    		if((letti = recvfrom(psockfd, &azione, 1, 0, (struct sockaddr *)&pclntddrss, &paddrlen)) < 0)
    		{
    			perror("Errore in lettura.\n");
    			exit(1);
    		}
    		
    		printf("L'azione scelta è: %c.\n", azione);
    		
    		//Creazione socket processo figlio
    		if((csockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
    		{
    			perror("Errore nella creazione del socket.\n");
    			exit(1);
    		}
    		
    		//Azzeramento dello spazio di memoria con l'indirizzo della variabile clntddrss
    		memset((void *)&cclntddrss, 0, sizeof(cclntddrss));
    		
    		//Assegnazione del tipo di indirizzo
    		cclntddrss.sin_family = AF_INET;
    		
    		//Connessioni accettate su qualunque interfaccia di rete
    		cclntddrss.sin_addr.s_addr = htonl(INADDR_ANY);
    		
    		//Assegnazione del numero di porta
    		cclntddrss.sin_port = htons(0);
    		
    		//Assegnazione dell'indirizzo al socket
    		if ((bind(csockfd, (struct sockaddr *)&cclntddrss, sizeof(cclntddrss))) < 0)
    		{
    			perror("Errore in bind.\n");
    			exit(1);
    		}
    		unsigned int dim = sizeof(temp);
    		getsockname(csockfd, (struct sockaddr *)&temp, &dim);
    		
    		printf("Il figlio ha la porta: %d.\n", ntohs(temp.sin_port));
    		
    		//Invio numero di porta del socket del processo figlio
    		if(scritti = sendto(psockfd, (int*)&temp.sin_port, 4, 0, (struct sockaddr *)&pclntddrss, sizeof(pclntddrss)) < 0)
    		{
    			perror("Errore in scrittura.\n");
    			exit(1);
    		}
    		
    		//Creazione del processo figlio
    		pid_t pid = fork();
    		
    		//Controllo errore pid
    		if(pid < 0) printf("Errore nella creazione del processo figlio.\n");
    		
    		//Codice processo figlio
    		if(pid == 0)
    		{
    			printf("Creato il figlio: %d.\n", getpid());
    			close(psockfd);
    			
    			if(azione == 'l' || azione == 'L')
    			{
    				
    				printf("L'utente ha richiesto la lista dei file.\n");
    				
    				//Directory di lavoro del server
    				getcwd(directory, sizeof(directory));
    				
    				//Apertura della directory
    				dp = opendir(directory);
    				printf("Directory aperta.\n");
    				
    				if(dp == NULL) exit(1);
    				
    				printf("Funziona.\n");
    				
    				dir_p = readdir(dp);
    				
    				//Apertura del file della lista. Se non esiste viene creato
    				list_fd = fopen(lista_file, "w+");
    				
    				//Scrittura nel file
    				while ((dir_p = readdir(dp)) != NULL)
    				{
    					if ((strcmp(dir_p -> d_name, "server.c") && strcmp(dir_p -> d_name, "server") && strcmp(dir_p -> d_name, "header.h")) != 0)
    					{
    						fprintf(list_fd, "%s\n", dir_p -> d_name);
    					}
    				}
    				
    				//Controllo della dimensione del file
    				//Spostamento a fine file
    				fseek(list_fd, 0L, SEEK_END);
    				
    				//La ftell ritorna la posizione
    				len = ftell (list_fd) + 1;
    				
    				printf("Il file occupa %d Byte.\n", len);
    				
    				//Spostmento ad inizio file
    				fseek(list_fd, 0L, SEEK_SET);
    				
    				fclose(list_fd);
    				
    				list_fd = fopen(lista_file, "rb");
    				
    				//Calcolo e trasmissione del numero di pacchetti necessari per l'invio
    				//Numero di pacchetti in cui verrà diviso il file
    				num_pack = len / MAXLINE;
    				
    				//Il resto è la dimensione dell'ultimo pacchetto
    				mod_pack = len % MAXLINE;
    				
    				//Arrotondamento del numero di pacchetto all'intero superiore
    				if (mod_pack > 0)
    				{ 
    					num_pack++;
    					printf("Il numero di pacchetti da inviare è: %d.\n", num_pack);
    					printf("La dimensione dell'ultimo pacchetto è: %d.\n", mod_pack);
    				}				
    				else
    				{
    					printf("Il numero di pacchetti da inviare è: %d.\n", num_pack);
    					mod_pack = MAXLINE;
    				}
    				
    				//Stampa di controllo
    				printf("mod_pack = %d.\n", mod_pack);
    				
    				//Invio il numero di pacchetti al client
    				if (scritti = sendto (csockfd, (int*)&num_pack, 4, 0, (struct sockaddr *)&cclntddrss, sizeof(cclntddrss)) < 0)
    				{
    					perror("Errore in scrittura.\n");
    					exit(1);
    				}
    				
    				//Invio la dimensione dell'ultimo pacchetto al client
    				if (scritti = sendto (csockfd, (int*)&mod_pack, 4, 0, (struct sockaddr *)&cclntddrss, sizeof(cclntddrss)) < 0)
    				{
    					perror("Errore in scrittura.\n");
    					exit(1);
    				}
    				
    				//Settggio a zero del numero di sequenza
    				inviato.num_seq = 0;
    				
    				for (i = 0; i < num_pack - 1; i++)
    				{
    					inviato.num_seq ++;
    					
    					//Leggo dal file la parte che mi interessa
    					fread(inviato.bit_string, MAXLINE, 1, list_fd);
    					//Invio della parte del file
    					if (scritti = sendto (csockfd, (void *)&inviato, sizeof(inviato), 0, (struct sockaddr *)&cclntddrss, sizeof(cclntddrss)) < 0)
    					{
    						perror("Errore in scrittura.\n");
    						exit(1);
    					}
    					
    					printf("%d / %d pacchetti inviati | Numero di sequenza del pacchetto: %d.\n", i+1, num_pack, inviato.num_seq);   //Una parte della stampa è di controllo
    				}
    				
    				ultimo_lista = (char*) malloc (mod_pack);
    				fread(ultimo_lista, mod_pack, 1, list_fd);
    				if(scritti = sendto (csockfd, ultimo_lista, mod_pack, 0, (struct sockaddr *)&cclntddrss, sizeof(cclntddrss)) < 0)
    				{
    					perror("Errore in scrittura.\n");
    					exit(1);
    				}
    				
    				printf("%d / %d pacchetti inviati | Numero di sequenza del pacchetto: %d.\n", i+1, num_pack, inviato.num_seq + 1);   //Una parte della stampa è di controllo
    				fclose (list_fd);
    				closedir(dp);
    				
    			}
    			//Chiusura socket figlio
    			close(csockfd);
    			
    			//Terminazione processo figlio
    			exit(EXIT_SUCCESS);
    		}
    		//Codice processo padre
    		else
    		{
    			//Chiusura socket figlio
    			close(csockfd);
    			
    			//Eliminazione degli zombie
    			waitpid (-1, NULL, WNOHANG);
    		}
    	}
    	exit(0);
    }
    e l'header:
    codice:
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <sys/stat.h>
    #include <sys/wait.h>
    #include <fcntl.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <time.h>
    #include <errno.h>
    #include <malloc.h>
    #include <signal.h>
    #include <dirent.h>
    
    #define SERV_PORT   3547
    #define BACKLOG       10
    #define MAXLINE     1024

  3. #3
    Benvenuto nel forum

    Messaggio molto dettagliato, ad eccezione di un punto fondamentale: cosa è che non va? Qual'è il problema riscontrato?

  4. #4
    grazie lol essendo il mio primo post sapevo che qualcosa l'avrei omessa in qualche modo lol...

    comunque il problema è che non riesco a far comunicare i processi figli tra di loro...
    finchè i padri devono svolgere le fasi preliminari non c'è problema, ma quando l'azione passa in mano ai figli non comunicano.
    questo non solo nel codice postato, ma anche tra tutte le varie prove che ho gia fatto.
    forse sbaglio qualcosa di fondo, non so proprio...

  5. #5
    Utente di HTML.it
    Registrato dal
    Jul 2008
    Messaggi
    1,326
    Purtroppo non ho modo di leggere tutto il codice, ma un errore di sicuro è qui:

    codice:
    if(scritti = sendto(psockfd, (int*)&temp.sin_port, 4, 0, (struct sockaddr *)&pclntddrss, sizeof(pclntddrss)) < 0)
    Analizza bene l'istruzione... di preciso, cosa stai assegnando a "scritti"? Direi che ci manca un paio di parentesi...

    Questa istruzione è nel server, ma non è l'unica a presentare questo tipo di errore (nel server ma anche nel client). Di sicuro sono da correggere, poi non so se il resto vada bene, purtroppo non ho tempo per controllare tutto.

    Non è la prima volta che si vedono errori del genere proprio su applicazioni client/server su Unix... davvero singolare.
    every day above ground is a good one

  6. #6
    mmm... a scritti viene assegnato il return della funzione sendto.
    però è strano perchè a me in altre prove (prima di implementare le fork) ha sempre funzionato anche così.
    ad esempio facendo l'assegnazione a scritti in una riga e poi la if nella successiva ottengo lo stesso identico risultato; magari è più "corretto" (anche se meno immediato) però (purtroppo) non risiede li il problema...

    comunque grazie per avermi risposto

  7. #7
    Utente di HTML.it
    Registrato dal
    Jul 2008
    Messaggi
    1,326
    No, a "scritti" stai assegnando il valore booleano di

    codice:
    sendto(psockfd, (int*)&temp.sin_port, 4, 0, (struct sockaddr *)&pclntddrss, sizeof(pclntddrss)) < 0
    ti mancano delle parentesi, fai attenzione alle regole di precedenza degli operatori. Devi aggiustare con

    codice:
    if ((scritti = sendto(psockfd, (int*)&temp.sin_port, 4, 0, (struct sockaddr *)&pclntddrss, sizeof(pclntddrss))) < 0)
    Hai un errore simile in diverse altre parti del codice.
    every day above ground is a good one

  8. #8
    ok; premesso che gia avevo provato a dare le prioritá per la correttezza e che comunque ci ho riprovato come consigliato da te, il risultato che ottengo é esattamente lo stesso (purtroppo) anche se metto l'assegnazione e il confronto su due righe di codice distinte.

    ora io lo lascio cosí per leggibilitá peró purtroppo, ai fini del funzionamento, non é cambiato nulla infatti anche l'out é identico: "errore in scrittura", "can't assign request address", e scritti = -1 (perché la sendto non va a buon fine dati gli errori che ho appena citato).

    se pensi che non abbia capito cosa mi volevi dire per favore non esitare a ribadire che sarei molto contento di sbagliarmi...
    sul serio.

    grazie ancora

    p.s.:
    mi ero scordato di aggiungere una cosa importante: come tu hai sottolineato ho questo costrutto in piú parti del codice; la cosa strana peró é che fin tanto che si parlano i processi padre tutto é ok, mentre l'errore c'é solo quando la comunicazione riguarda i figli (é anche sull a base di questo che ti avevo risposto che il problema non poteva risiedere qui)

  9. #9
    ho fatto un esempio ancora più snello ma con la stessa dinamica che evidenzia proprio il problema.

    il client invia un int al server che lo riceve;
    il server crea una socket per il child e invia il numero di porta al client che lo riceve;
    il client crea un child che invia un int al child del server che lo riceve;
    il child del server invia un int al child del client, ma qualcosa va storto...

    non riesco proprio a capire ma il problema è generato proprio da quel sendto e molto probabilmente per colpa del cclntddrss.

    posto il relativo codice; l'header è lo stesso del precedente.

    client:
    codice:
    #include "header.h"
    
    int psockfd, csockfd, pscritti, cscritti, pletti, cletti, spadre = 0, lfiglio = 0, sfiglio = 0;
    unsigned int paddrlen, caddrlen;
    int ricporta;
    struct sockaddr_in psrvrddrss;
    struct sockaddr_in csrvrddrss;
    
    int main(int argc, char** argv)
    {
    	printf("Prova.\n");
    	//Controllo numero argomenti
    	if (argc != 2)
    	{
    		perror("Indirizzo del server ip mancante.\n");
    		exit(1);
    	}
    	
    	//Creazione del socket del processo padre
    	if ((psockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
    	{
    		perror("Errore nella creazione del socket.\n");
    		exit(1);
    	}
    	
    	//Svuotamento srvraddrss
    	memset((void *)&psrvrddrss, 0, sizeof(psrvrddrss));
    	
    	//Assegnazione del tipo di indirizzo
    	psrvrddrss.sin_family = AF_INET;
    	
    	//Assegnazione porta del servar
    	psrvrddrss.sin_port = htons (SERV_PORT);
    	
    	/*Assegnazione dell'indirizzo del server tramite riga di comando
    	 l'indirizzo è una stringa e va convertito in network byte order*/
    	if (inet_pton(AF_INET, argv[1], &psrvrddrss.sin_addr) <= 0)
    	{
    		fprintf(stderr, "Errore in inet_pton per %s.\n", argv[1]);
    		exit(1);
    	}
    	
    	paddrlen = sizeof(psrvrddrss);
    	
    	printf("Premi un tasto qualsiasi per inviare.\n");
    	getchar();
    	spadre = 5;
    	pscritti = sendto(psockfd, (int*)&spadre, 4, 0, (struct sockaddr*)&psrvrddrss, sizeof(psrvrddrss));
    	if(pscritti < 0)
    	{
    		perror("Errore in scrittura.\n");
    		exit(1);
    	}
    	
    	//Ricezione numero di porta del server
    	pletti = recvfrom(psockfd, (int*)&ricporta, 2, 0, (struct sockaddr*)&psrvrddrss, &paddrlen);
    	if(pletti < 0)
    	{
    		perror("Errore in lettura.\n");
    		exit(1);
    	}
    	printf("Prova.\n");
    
    	printf("Numero porta figlio server: %d.\n", ntohs(ricporta));
    	
    	//Creazione del socket del processo figlio
    	if ((csockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
    	{
    		perror("Errore nella creazione del socket.\n");
    		exit(1);
    	}
    	
    	caddrlen = sizeof(csrvrddrss);
    	//Svuotamento srvraddrss
    	memset((void *)&csrvrddrss, 0, sizeof(csrvrddrss));
    	
    	//Assegnazione del tipo di indirizzo
    	csrvrddrss.sin_family = AF_INET;
    	
    	//Assegnazione porta del servar
    	csrvrddrss.sin_port = ricporta;
    	printf("Il numero di porta ricevuto è: %d , %d.\n", htons(csrvrddrss.sin_port), htons(ricporta));
    	/*Assegnazione dell'indirizzo del server tramite riga di comando
    	 l'indirizzo è una stringa e va convertito in network byte order*/
    	if (inet_pton(AF_INET, argv[1], &csrvrddrss.sin_addr) <= 0)
    	{
    		fprintf(stderr, "Errore in inet_pton per %s.\n", argv[1]);
    		exit(1);
    	}
    	
    
    	//Creazione processo figlio
    	pid_t pid = fork();
    	
    	//Controllo di errore pid
    	if(pid < 0) printf("Errore nella creazione del processo figlio.\n");
    	
    	//Codice processo figlio
    	if(pid == 0)
    	{
    		printf("Creato il figlio: %d.\n", getpid());
    		//Chiusura socket del padre
    		close(psockfd);
    		
    		printf("Premi un tasto qualsiasi per inviare.\n");
    		getchar();
    		
    		sfiglio = 7;
    		
    		cscritti = sendto(csockfd, (int*)&sfiglio, 4, 0, (struct sockaddr*)&csrvrddrss, sizeof(csrvrddrss));
    		if(cscritti < 0)
    		{
    			perror("Errore in scrittura.\n");
    			exit(1);
    		}
    
    		
    		cletti = recvfrom(csockfd, (int*)&lfiglio, 2, 0, (struct sockaddr*)&csrvrddrss, &caddrlen);
    		if(cletti < 0)
    		{
    			perror("Errore in lettura.\n");
    			exit(1);
    		}
    		
    		printf("Il figlio ha letto: %d.\n", lfiglio);
    		
    		close(csockfd);
    		exit(EXIT_SUCCESS);
    	}
    	wait(NULL);
    	exit(0);
    }

  10. #10
    e questo è il relativo server:

    codice:
    #include "header.h"
    
    int psockfd, csockfd, pletti, cletti, pscritti, cscritti, lpadre = 0, sfiglio = 0, lfiglio = 0;
    unsigned int paddrlen, caddrlen;
    struct sockaddr_in temp;
    struct sockaddr_in pclntddrss;
    struct sockaddr_in cclntddrss;
    
    int main()
    {
    	//Creazione del socket del processo padre
    	if((psockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
    	{
    		perror("Errore nella creazione del socket.\n");
    		exit(1);
    	}
    	
    	//Azzeramento dello spazio di memoria con l'indirizzo della variabile clntddrss
    	memset((void *)&pclntddrss, 0, sizeof(pclntddrss));
    	
    	//Assegnazione del tipo di indirizzo
    	pclntddrss.sin_family = AF_INET;
    	
    	//Connessioni accettate su qualunque interfaccia di rete
    	pclntddrss.sin_addr.s_addr = htonl(INADDR_ANY);
    	
    	//Assegnazione del numero di porta
    	pclntddrss.sin_port = htons(SERV_PORT);
    	
    	//Assegnazione dell'indirizzo al socket
    	/*nella prima parte struct sockaddr... fino alla virgola, cambia il tipo della variabile clntddrss*/
    	if ((bind(psockfd, (struct sockaddr *)&pclntddrss, sizeof(pclntddrss))) < 0)
    	{
    		perror("Errore in bind.\n");
    		exit(1);
    	}
    	printf("Il padre ha la porta: %d.\n", ntohs(pclntddrss.sin_port));
    	
    	paddrlen = sizeof(pclntddrss);
    	
    	pletti = recvfrom(psockfd, (int*)&lpadre, 4, 0, (struct sockaddr*)&pclntddrss, &paddrlen);
    	if( pletti < 0)
    	{
    		perror("Errore in lettura.\n");
    		exit(1);
    	}
    	
    	printf("Il padre ha letto: %d.\n", lpadre);
    	
    	
    	//Creazione socket processo figlio
    	if((csockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
    	{
    		perror("Errore nella creazione del socket.\n");
    		exit(1);
    	}
    	
    	//Azzeramento dello spazio di memoria con l'indirizzo della variabile clntddrss
    	memset((void *)&cclntddrss, 0, sizeof(cclntddrss));
    	
    	//Assegnazione del tipo di indirizzo
    	cclntddrss.sin_family = AF_INET;
    	
    	//Connessioni accettate su qualunque interfaccia di rete
    	cclntddrss.sin_addr.s_addr = htonl(INADDR_ANY);
    	
    	//Assegnazione del numero di porta
    	cclntddrss.sin_port = htons(0);
    	
    	//Associazione del processo al socket
    	if ((bind(csockfd, (struct sockaddr *)&cclntddrss, sizeof(cclntddrss))) < 0)
    	{
    		perror("Errore in bind.\n");
    		exit(1);
    	}
    	unsigned int dim = sizeof(temp);
    	getsockname(csockfd, (struct sockaddr *)&temp, &dim);
    	
    	printf("Il figlio ha la porta: %d.\n", ntohs(temp.sin_port));
    	
    	printf("Premere un tasto per inviare.\n");
    	getchar();
    	
    	//Invio numero di porta del socket del processo figlio
    	pscritti = sendto(psockfd, (int*)&temp.sin_port, 2, 0, (struct sockaddr*)&pclntddrss, sizeof(pclntddrss));
    	if(pscritti < 0)
    	{
    		perror("Errore in scrittura.\n");
    		exit(1);
    	}
    	
    	
    	//Creazione del processo figlio
    	pid_t pid = fork();
    	
    	//Controllo errore pid
    	if(pid < 0) printf("Errore nella creazione del processo figlio.\n");
    	
    	//Codice processo figlio
    	if(pid == 0)
    	{
    		printf("Creato il figlio: %d.\n", getpid());
    		close(psockfd);
    		
    		pletti = recvfrom(csockfd, (int*)&lfiglio, 4, 0, (struct sockaddr*)&cclntddrss, &caddrlen);
    		if (cletti < 0)
    		{
    			perror("Errore in lettura.\n");
    			exit(1);
    		}
    		
    		printf("Il figlio ha letto: %d.\n", lfiglio);
    		
    		printf("Premere un tasto per inviare.\n");
    		getchar();
    		sfiglio = 9;
    		cscritti = sendto(csockfd, (int*)&sfiglio, 2, 0, (struct sockaddr *)&cclntddrss, sizeof(cclntddrss));
    		if (cscritti < 0)
    		{
    			perror("Errore in scrittura.\n");
    			exit(1);
    		}
    		
    		//Chiusura socket figlio
    		close(csockfd);
    			
    		//Terminazione processo figlio
    		exit(EXIT_SUCCESS);
    	}
    	wait(NULL);
    	exit(0);
    }

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.