Bonjour à tous,

je me permets de vous déranger pour vous poser une question concernant l'envoi d'accusés de réception par un serveur.
En Licence 3 Informatique, nous devons coder un petit serveur et un petit client permettant simplement d'envoyer un message (du client vers le serveur) puis d'envoyer un accusé de réception à ce même client. Or, si la première partie fonctionne, la deuxième a tendance à planter...

Code du client :
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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#define Internet_Port 2074
#define TAILLE_MAX_MSG 256
/*
Programme client en mode connecté : échange de séquences de caractères continues et non structurées
*/
main(argc,argv)
int argc;
char **argv;
{
	int sd, lon, nsr;
	struct sockaddr_in adsock;
	struct hostent *hptr;
	struct servent *sptr;
	char buf[13];
	char *prog;
	char *host;
	char mesg[8]="BONJOUR";
	prog = argv[0];
	if(argc!=2)
	{
		perror("Il faut un argument");
		exit(1);
	}
	host=argv[1];
	//Infos du host
	if((hptr=gethostbyname(host))==NULL)
	{
		perror("Probleme Info sur le host");
		exit(1);
	}
	/*
	Initialiser le adsock avec les infos du host pour préparer adresse d'attachement
	*/
	bcopy((char *)hptr->h_addr,(char *)&adsock.sin_addr.s_addr,hptr->h_length);
	adsock.sin_family=hptr->h_addrtype;
	//récupération du numéro de port
	adsock.sin_port = htons(Internet_Port);
	//création du socket
	if((sd=socket(AF_INET,SOCK_STREAM,0))<0)
	{
		perror("Erreur lors de la creation du socket");
		close(sd);
		exit(1);
	}
	//connexion serveur
	if((connect(sd,&adsock,sizeof(adsock)))<0)
	{
		perror("Erreur connexion");
		close(sd);
		exit(1);
	}
	//envoi requête
	if((write(sd,mesg,8))<0)
	{
		perror("Erreur lors de l'ecriture");
		exit(1);
	}
	lon=sizeof(adsock);
	if((nsr=accept(sd,&adsock,&lon))<0)
	{
		close(nsr);
		perror("Erreur accept");
		exit(1);
	}else{
		recv(nsr,buf,13,0);
		printf("%s \n",buf);
		close(nsr);
	}
	close(sd);
	exit(0);
}
Code du serveur :
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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#define Internet_Port 2074
#define TAILLE_MAX_MSG 256
 
main(int argc, char **argv)
{
	int sd, lon, nsd, i, sr;
	struct sockaddr_in adsock, adacc;
	struct hostent *hptr;
	struct servent *sptr;
	char buf[8];
	char ack[13]="MESSAGE RECU";
	char *prog;
	char *host;
	prog = argv[0];
	if(argc!=2)
	{
		perror("Il faut un argument");
		exit(1);
	}
	host=argv[1];
	//Infos du host
	if((hptr=gethostbyname(host))==NULL)
	{
		perror("Probleme Info sur le host");
		exit(1);
	}
	/*
	Initialiser le adsock avec les infos du host pour préparer adresse d'attachement
	*/
	adsock.sin_family=AF_INET;
	adsock.sin_addr.s_addr=htonl(INADDR_ANY);
	//récupération du numéro de port
	adsock.sin_port = htons(Internet_Port);
	//création du socket
	if((sd=socket(AF_INET,SOCK_STREAM,0))<0)
	{
		perror("Erreur lors de la creation du socket");
		close(sd);
		exit(1);
	}
	if((bind(sd,&adsock,sizeof(adsock)))<0)
	{
		close(sd);
		perror("Erreur lors du bind");
		exit(1);
	}
	listen(sd,5);
	//boucle attente connexions
	for(;;)
	{
		lon=sizeof(adsock);
		if((nsd=accept(sd,&adsock,&lon))<0)
		{
			close(nsd);
			perror("Erreur accept");
			exit(1);
		}else{
			recv(nsd,buf,8,0);
			printf("Message recu : %s \n",buf);
			close(nsd);
		}
		//envoi de l'acknowledgement
		if((send(sd,ack,13,0))<0)
		{
			perror("Erreur lors de l'ecriture");
			exit(1);
		}
	}
	close(sd);
	exit(0);
}
Lorsque je lance le client, le message apparaît bien sur le serveur, mais le client plante lors de la tentative de réception de l'acknowledgment :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
Erreur accept: Bad file descriptor
Et le serveur plante totalement lui aussi après réception du message.

Concernant les codes, le client nous a été donné, et le début du serveur (réception du message et affichage) a été corrigé avec notre professeur.
Celà fait deux semaines que je cherche à résoudre ce problème, et je ne sais plus quoi faire. Avez-vous une idée ?

Cdlt,

Vrashnak