Bonsoir à tous,

Je dois effectuer une application client/serveur de DL/UL de fichiers.
Je suis malheureusement bloqué par une erreur que je ne comprends pas. J'ai essayé plein de choses, mais j'arrive à un point de non retour ^^.

Voici mon 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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
 
 
#include <stdlib.h>
#include <stdio.h>
#include <linux/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <string.h>
#include <errno.h> 
#include "afps.h"
 
typedef struct sockaddr_in sockaddr_in;
typedef struct sockaddr sockaddr;
typedef struct aspartrame aspartrame;
 
int initbuf(char* buf){
	char* tmp = buf;
	for(tmp; tmp < buf + strlen(buf); tmp++){
		*tmp = 0;
	}
	return EXIT_SUCCESS; 
}
 
//Fonction de construction de l'aspartrame
void make_aspartrame(aspartrame* asp, char* action, char* data, char remains){
	strcpy(asp->action, action);
	asp->remains = remains;
	strcpy(asp->data, data);
	asp->data_size = strlen(asp->data);
}
 
int main(int argc,char** argv){
 
	aspartrame asp = {0};
 
	FILE* log;
	log = fopen("serv.log", "w+");
 
	int sd;		/* Socket Descriptor */
	int arg_port = 0;
	int domain, type, protocol;
	domain = type = protocol = 0;
    char cmd[5] = {0};
    char arg[101] = {0};
    char path[256] = {0};
    char data_buf[8000000] = {0};
    FILE* file;
 
	/* creation du socket */
	printf("creation socket\n");
	sd = socket(AF_INET, SOCK_STREAM, 0);
	if(sd == INVALID_SOCKET){
    	perror("socket()");
   	 	exit(errno);
	}
 
	/* creation de l'interface */
	printf("creation interface\n");
	sockaddr_in sin = { 0 }; //structure d'adresse locale
	sin.sin_addr.s_addr = htonl(INADDR_ANY); //On se met en écoute de toutes les adresses
	sin.sin_family = AF_INET;
 
	sin.sin_port = htons(PORT);
 
	//Affichage de l'en tête serveur de debug
	printf(" ------- Lancement du serveur de fichier(s) \n");
	printf(" ------- Port d'ecoute : %d\n", arg_port);
 
	if( bind(sd, (sockaddr *) &sin, sizeof(sin) ) == SOCKET_ERROR)
	{
	    perror("bind()");
	    exit(errno);
	}
 
	/* Configuration de la file d'attente et démarrage de l'écoute */
	printf("demarrage ecoute\n");
	if(listen(sd, SIMULTANEOUS_CONNECTIONS) == SOCKET_ERROR)
	{
		perror("listen()");
		exit(errno);
	}
 
	sockaddr_in csin = { 0 };
	int csd = 0; // Client Socket Descriptor
	int sinsize = 0;
	char buf[256] = { 0 };
	char motcode[32] = { 0 };
 
	while(1){
		sinsize = sizeof csin;
 
		//Autorisation de connexion et création d'un nouveau socket pour la communication
		csd = accept(sd, (sockaddr *)&csin, &sinsize);
		printf("CSD = %d\n",csd);
		printf("SD = %d\n", sd);
 
		make_aspartrame(&asp, "msg", "hello!", 0);
		printf("coucou\n");
		printf("pointeur asp = %p\n", &asp);
		printf("Asp.action = %s\n",asp.action);
		printf("Asp.data = %s\n",asp.data);
		send(csd,"pouet",sizeof(asp), 0);
 
		//send(csd,&asp,sizeof(asp), 0);
		//send(csd,"A4PH9",6, 0);
		/* envoi message de bienvenue */
		initbuf(buf);
		//printf("Strlen(buf) = %d",strlen(buf));
		recv(csd,&asp,sizeof(asp),0);
		//printf("Strlen(buf) = %d",strlen(buf));
		//printf("Buf = %s\n",buf);
 
 
		if(strcmp(asp.data, "ready?")){ //Si la data ne contient pas "ready?"
			printf("Client n'utilisant pas le protocole :%s.\n", asp.data);
			close(csd);
		}else{
			printf("Client utilisant le protocole :%s.\n", asp.data);
			make_aspartrame(&asp, "msg", "ready!", 0);
			printf("coucou\n");
			printf("pointeur asp = %p\n", &asp);
			printf("Asp.action = %s\n",asp.action);
			printf("Asp.data = %s\n",asp.data);
			send(csd,&asp,sizeof(aspartrame), 0);
			printf("Confirmation de connexion envoyée : %s\n", asp.data);
//			fopen("schtroumpf", "w+");
 
			// ecoute permanente
			while(csd != INVALID_SOCKET){
				if( csd < 0 ){
					perror("accept()");
					exit(errno);
				}
 
				/* Attente du paquet client */
				//initbuf(buf);
		  		//int lon;
		  		//if ((lon = read(csd, buf, sizeof(buf))) <=0) return;
		  		recv(csd, &asp, sizeof(asp), 0);
		  		//buf[lon-1] = '\0';
		  		//printf("Message reçu\n");
 
		  		/* Interprétation du contenu */
		        //sscanf(buf, "%s %[^\n]", cmd, arg);
		        printf("\nValeurs saisies");
		        printf("Cmd=%s.\n",asp.action);
		        printf("Data=%s.\n",asp.data);
 
		  		if(!strcmp(asp.action, "stop")){
		  			printf("fermeture csd\n");
		  			close(csd);
		            csd = 0;
		        //Cas du téléchargement de fichier
		        }else if(!strcmp(asp.action, "dl")){
		        	printf("vous souhaitez télécharger le fichier %s.\n", asp.data);
 
		        	strcpy(path, DEFAULT_PATH);
		        	strcat(path, asp.data);
		        	file = fopen(path, "rb");
		        	if( file == NULL){
		        		printf("Le fichier %s n'existe pas\n", path);
		        	}else{
		        		printf("Le fichier %s existe bien\n", path);
		        		fread(data_buf, DATA_MAX_SIZE, 1, file);
		        		make_aspartrame(&asp, "dlr", data_buf, 0);
		        		send(csd,&asp,sizeof(asp), 0);
		        	}
 
		  		}else if(!strcmp(asp.action, "ul")){
		        	printf("vous souhaitez télécharger le fichier %s", asp.data);
 
		  		}else{
		  			printf("Ce n'est pas une commande correcte !\n");
		  		}
		  		if(!strcmp(asp.action, "client")){
		  			printf("SERVEUR !\n");
		  		}
		  		//initbuf(cmd);
		  		//initbuf(arg);
			}
		}
	}
 
	/* fermeture du socket */
	close(sd);
	fclose(log);
	return EXIT_SUCCESS; 
}
Mon serveur bloque au moindre envoi de structure "aspartrame". J'ai essayé avec un simple envoi de char* et ça fonctionne dans ce cas.

Voici le 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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
 
 
#include <stdlib.h>
#include <stdio.h>
#include <linux/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <string.h>
#include <errno.h> 
#include "afps.h"
 
typedef struct sockaddr_in sockaddr_in;
typedef struct sockaddr sockaddr;
typedef struct in_addr in_addr;
typedef struct aspartrame aspartrame;
 
int initbuf(char* buf){
	char* tmp = buf;
	for(tmp; tmp < buf + strlen(buf); tmp++){
		*tmp = 0;
	}
	return EXIT_SUCCESS; 
}
 
//Fonction de construction de l'aspartrame
void make_aspartrame(aspartrame* asp, char* action, char* data, char remains){
	strcpy(asp->action, action);
	asp->remains = remains;
	strcpy(asp->data, data);
	asp->data_size = strlen(asp->data);
}
 
int main(int argc,char** argv){
	FILE* log;
	log = fopen("cli.log", "w+");
	aspartrame asp = {0};
	char* prog;
	char* host;
	/* char* fichier;
	char* nom_fichier; */
 
	/* test des arguments */
	if (argc<2||argc>3){
		/* pas d'argument */
		perror("Erreur arguments\narguments : host (adresse ip)\n");
		exit(1);
	}
 
	/* recuperation des arguments */
	printf("Recuperation des arguments :\n");
	prog = argv[0];
	host = argv[1];
	//fichier = argv[2];
	//if(argv[3]==NULL) nom_fichier = argv[2];
	//else nom_fichier= argv[3];
	printf("prog : %s\n",prog);
	printf("host : %s\n",host);
	//printf("fichier : %s\n",fichier);
	//printf("nom fichier : %s\n",nom_fichier);
 
	/* -----------------------------------------*/
 
	/* creation du socket */
	int sd = 0;
	sd = socket(AF_INET, SOCK_STREAM, 0);
	if(sd == INVALID_SOCKET){
    	perror("socket()");
   	 	exit(errno);
	}
 
	/* connexion au serveur */
	struct hostent *hostinfo = NULL;
	sockaddr_in sin = { 0 }; /* initialise la structure avec des 0 */
 
	hostinfo = gethostbyname(host); /* on récupère les informations de l'hôte auquel on veut se connecter */
	if (hostinfo == NULL) /* l'hôte n'existe pas */
	{
		printf ("Unknown host %s.\n", host);
		exit(EXIT_FAILURE);
	}
 
	sin.sin_addr = *(in_addr *) hostinfo->h_addr; /* l'adresse se trouve dans le champ h_addr de la structure hostinfo */
	sin.sin_port = htons(PORT); /* on utilise htons pour le port */
	sin.sin_family = AF_INET;
 
	if(connect(sd,(sockaddr *) &sin, sizeof(sockaddr)) == SOCKET_ERROR)
	{
		perror("connect()");
		exit(errno);
	}
	// la connexion est établie
 
	/* envoi */
 
	char buffer[1024];
 
	recv(sd, &asp, sizeof(asp), 0);
 
	if(strcmp(asp.data, "hello!")) return;
 
	make_aspartrame(&asp, "msg", "ready?", 0); 
 
	if(send(sd, &asp, sizeof(asp), 0) < 0)
	{
		perror("send()");
		exit(errno);
	}
 
	printf("Demande de connexion envoyee\n");
	printf("\n");
 
	recv(sd, &asp, sizeof(asp), 0);
	printf("DATA = %s", asp.data);
 
	/*while(&sd != NULL){
		printf("Tchou tchou\n");
		close(sd);
	}*/
	fclose(log);
}
Mon client n'a pas de problèmes pour envoyer la structure au serveur qui peut les lire.

Tout ça me semble très louche, car c'est un contexte particulier qui n'est pas possible (envoi d'une structure trame, du serveur au client).

Cela m'ennuie de devoir passer par des buffers simples pour passer l'information car je sais que la communication par structure est possible.

Please help !

Merci de m'avoir lu.