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);
}