Pagina 2 di 2 primaprima 1 2
Visualizzazione dei risultati da 11 a 13 su 13
  1. #11
    Utente di HTML.it
    Registrato dal
    Jul 2008
    Messaggi
    1,326
    Direi di rivedere i campi "len" di ogni sendto/recvfrom. Ricorda che il campo sin_port di sockaddr_in è di tipo unsigned short, quindi con ogni probabilità è su 2 byte, non 4 (per evitare certi tipi di problemi, comunque, basta che nel campo len ci scrivi "sizeof(nome_struct.sin_port)").
    Inoltre, considera l'ultima sendto del server (quella che ti dà problemi): hai scritto che il numero di byte da inviare è 2, ma con ogni probabilità gli int col tuo compilatore sono di 4 byte (ancora una volta, basta scrivere sizeof(int) o sizeof(sfiglio) per non avere problemi). E altro problema, forse ancora più serio: considera l'ultima recvfrom del server (la prima del processo figlio): quale valore ha caddrlen? Non mi pare gli assegni un valore da nessuna parte... scrivi qualche riga di codice prima "caddrlen = sizeof(cclntddrss);". Anche i cast a "int *" nel caso di sin_port vanno rivisti...

    Per farla breve, questi a me funzionano (nota soprattutto l'assegnazione del valore a caddrlen prima della fork() nel server)

    (e per carità, elimina quella serie di variabili globali che non si possono guardare, oltre al fatto di essere inutili in quel caso )

    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, (unsigned short *)&temp.sin_port, 2, 0, (struct sockaddr*)&pclntddrss, sizeof(pclntddrss));
    	if(pscritti < 0)
    	{
    		perror("Errore in scrittura.\n");
    		exit(1);
    	}
    	
    	caddrlen = sizeof(cclntddrss);
    	
    	
    	//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, 4, 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);
    }
    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, (unsigned short *)&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, 4, 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);
    }
    every day above ground is a good one

  2. #12
    si purtroppo è molto grezzo perchè l'ho dovuto estrarre come esempio per postarlo un pò di fretta.

    comunque hai fatto una serie di osservazioni molto interessanti domani le proverò e non vedo l'ora; grazie 10^3.

  3. #13
    rispondo solo ora perché ho avuto dei contrattempi, comunque...

    FUNZIONA!

    grazie veramente, rileggendolo sempre con gli stessi occhi per quante volte potessi provare non riuscivo mai a capire fino in fondo...

    grazie per l'attenzione, grazie per il tempo... grazie di tutto

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 © 2026 vBulletin Solutions, Inc. All rights reserved.