Bonjour à tous!
J'ai réalisé récemment un programme client-serveur (plutôt basique) fonctionnant en UDP en local... Si je le teste via loopback il fonctionne bien, mais l'ayant testé sur 2 autres machines d'un réseau local, il segfault (j'ignore si la segfault vient du fait que ma machine "tolère" une erreur ou du fait que ce soit vraiment lié au fait qu'on ne passe pas par le loopback).
SERVEUR
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 #include <sys/socket.h> #include <netinet/in.h> #include <string.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #define PORT 4242 int main() { struct sockaddr_in addr; int sock; int debut=1; int connected=0; //nombre connexions char buffer[256]; struct sockaddr peer[5]; int ipeer=0,i=0; struct sockaddr addr_peer; socklen_t addrlen; sock = socket(AF_INET,SOCK_DGRAM,0); if (sock==-1) { perror("socket: "); exit(EXIT_FAILURE); } addr.sin_family = AF_INET; addr.sin_port = htons(PORT); addr.sin_addr.s_addr = htonl(INADDR_ANY); addrlen=sizeof(addr_peer); if (bind(sock,(struct sockaddr *)(&addr),sizeof(addr))==-1) { perror("bind: "); close(sock); exit(EXIT_FAILURE); } while (connected!=0 || debut==1) { if (recv(sock,buffer,256,0)==-1) { perror("recv: "); close(sock); exit(EXIT_FAILURE); } else if (strcmp(buffer, "CONNECTION")==0) { getpeername(sock,&addr_peer,&addrlen); peer[ipeer]=addr_peer; debut=0; connected++; ipeer++; } else if(strcmp(buffer, "QUIT\n")==0){ connected--; } else { getpeername(sock,&addr_peer,&addrlen); while(strcmp(addr_peer.sa_data,peer[i].sa_data)) i++; printf("Reçu par %s : %s \n ",addr_peer.sa_data,buffer); i=0; } } close(sock); return 0; //connecté est utile pour savoir le nombre de connexions : quand une connexion a déja été établie et que plus personne n'est connecté, le serveur se ferme de lui-même }
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 #include <stdio.h> #include <netdb.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <arpa/inet.h> #include <sys/types.h> #include <netinet/in.h> #include <sys/socket.h> #define PORT 4242 int main(int argc,char *argv[]) { //création struct struct sockaddr_in addr; int sock; char buff[256]; struct hostent *host; int signal=1; //1 ssi premier message, 2 si deconnexion if (argc<2) { fprintf(stderr,"usage: %s host\n",argv[0]); exit(EXIT_FAILURE); } //récupération de l'IP de l'hote host = gethostbyname(argv[1]); if (host==NULL) { fprintf(stderr,"%s: host %s unknown\n",argv[0],argv[1]); exit(EXIT_FAILURE); } //création socket UDP sock = socket(AF_INET,SOCK_DGRAM,0); //erreur si sock=-1 if (sock==-1) { perror("socket: "); exit(EXIT_FAILURE); } addr.sin_family = AF_INET; //famille adresse addr.sin_port = htons(PORT); //port memcpy(&(addr.sin_addr.s_addr),host->h_addr_list[0],host->h_length); while(signal!=2){ if (sendto(sock,buff ,256,0,(struct sockaddr *)(&addr),sizeof(addr))==-1) { perror("sendto:"); close(sock); exit(1); } if (signal==1){ sendto(sock,"CONNECTION", 11,0, (struct sockaddr *)(&addr), sizeof(addr)); signal=3; } strcpy(buff ,fgets(buff,256, stdin)); if (strcmp(buff, "QUIT\n")==0){ sendto(sock,buff,6,0,(struct sockaddr *)(&addr), sizeof(addr)); signal=2; } } close(sock); return 0; }
Si ça peut vous aiguiller, valgrind est franchement généreux sur les erreurs : le fait que addr_peer soit initiailisé dans un else if dans le serveur ne lui plait pas (mais est-ce grave?). Quant au programme client, j'hérite d'un "Source and destination overlap in strcpy", il me semble pas que ça soit très grave non plus... Je vois pas vraiment d'où pourrait venir l'erreur qui fait segfault du coup... Des idées?
(Il y a aussi un problème dans la réception des addresses (on reçoit du garbage), n'y aurait-il pas un problème de htonl ou autre?)
Merci
Partager