Bonjour,

Je suis en cours de développement d'une application, et entre autre, celle-ci a besoin de recevoir des communications TCP de multiples clients.

J'ai donc fait une boucle dans le processus parent qui accepte les connexions et les distribue à ses fils :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
 
while (stop_process==0) {
	new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size);
	if (new_fd == -1) {
		syslog(LOG_INFO,"accept");
		exit(0);
	}
 
	if (!fork()) { 
		close(sockfd); 
		int byte_recv=0;
		char *receive_thread = malloc(sizeof(char)*receive_size);
		request request_in;
 
	        request_in.status=0;
		while (request_in.status < 5) {
			if ((byte_recv=recv(new_fd,receive_thread,receive_size,0)) <= 0) {
				syslog(LOG_INFO,"Erreur receive 1");close(new_fd);exit(0);
			}
			receive_thread[byte_recv-1]=0;
			do_process_request(receive_thread,new_fd,&request_in);
		}
		free(receive_thread);
		//sleep (5);
		if (request_in.status == 5) { // receive finished but no response
			send(new_fd, ok_status, 17, 0);
			if (request_in.xml_size>0) { free (request_in.xml);}
		}
 
		//printf("Closing session %i\n",new_fd);
		//sleep(1);
		close(new_fd);
		sleep(1); // wait for parent to close session (WHY ????).
		exit(0);
	}
	//printf("Parent Closing session %i\n",new_fd);
	if (close(new_fd) == -1) {syslog(LOG_INFO,"Error PARENT Closing session");}
}
Note : do_process_request traite la demande comme son nom l'indique

Tout se passe bien en test avec un telnet, mais lorsque c'est le vrai client qui se connecte (et donc envoi toutes les infos dans un seul paquet), le processus fils passe en "defunct", le parent à l'air bloqué (il n'accepte plus de connexions et la fonction lié à SIGCHLD - et contenant un wait() - n'est pas exécutée).

Avec un peu de debug, j'ai remarqué que le fils fermait la connexion avant le père, j'ai donc rajouté un sleep avant le close du fils (celui qui est commenté), mais cela me créait des latences de connexion.

En mettant le sleep juste avant l'exit du fils (comme c'est le cas actuellement), cela fonctionne assez bien.

Ma question est : pourquoi le fils passe en defunct et le père bloque sans ce sleep ?
Pourquoi le père met il aussi longtemps pour fermer la connexion ( pour lui c'est l'instruction suivante !) ?
Est-ce que ma structure de programme est foireuse ? ( j'ai pourtant sur ce point fait du copier/coller de programmes existants).

Merci d'avance