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
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
 
}
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
#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