Bonjour à tous,

Je commence à être agacé par le fameuse erreur lors d'un bind():
"Address already in use".

Le problème est connu, lorsqu'on programme un serveur on attache un socket à un port pour écouter les connexions.

Lorsque qu'on coupe le serveur et que l'on redémarre tout de suite on obtient généralement cette erreur.

Pour l'éviter, il y a (soi disant) :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
 
// lose the pesky "Address already in use" error message
  if(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
    logger_errno("setsockopt");
    pthread_exit(NULL);
  }
Mais ca ne marche pas vraiment, c'est même pire.

Après il faut aussi (soi disant) que le client soit l'initiateur de la fermeture, Client Closes First (ici)

Mais ca ne marche pas vraiment non plus ...
Comment faites vous ?
Voilà un exemple de code que j'utilise :

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
 
//Threaded server TCP
void *startServer(void *arg) {
 
  //sockets
  int sockfd, new_fd = 0;
  struct sockaddr_in my_addr;
  struct sockaddr_in their_addr;
  socklen_t sin_size;
  int yes = 1;
  int port;
 
  char recv_buffer[MAX_RECV_CHAR];
  port = (int) arg;
 
  sockfd = socket(PF_INET, SOCK_STREAM, 0);
  PFVERB("Server listening on port %d\n", port);
  if(sockfd == -1) {
    logger_errno("socket() failed on main()");
    pthread_exit(NULL);
  }
 
  my_addr.sin_family = AF_INET;	    // host byte order
  my_addr.sin_port = htons(port);	// short, network byte order
  my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
  memset(my_addr.sin_zero, '\0', sizeof my_addr.sin_zero);
 
  if(bind(sockfd, (struct sockaddr *) &my_addr, sizeof my_addr) == -1) {
    logger_errno("bind() error");
    PFVERB("bind() error\n");
    pthread_exit(NULL);
  }
  PFVERB("Socket binded\n");
 
  // lose the pesky "Address already in use" error message
  if(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
    logger_errno("setsockopt");
    pthread_exit(NULL);
  }
 
  if(listen(sockfd, 10) == -1) {
    logger_errno("listen()");
    pthread_exit(NULL);
  }
 
 
  while(halt == 0) {
 
    sin_size = sizeof their_addr;
    if((new_fd = accept(sockfd, (struct sockaddr *) &their_addr, &sin_size)) == -1) {
      logger_errno("accept() error");
    } else {
      printf("server: got connection from %s\n",inet_ntoa(their_addr.sin_addr));
      if((sendTCP("Welcome\r\nUse help command\r\n", new_fd)) <= 0) {
        logger_errno("sendTCP() error");
      }
    }
    while(halt == 0) {
 
      if((sendTCP("$>", new_fd)) <= 0) {
        logger_errno("sendTCP() error");;
      } else {
        if(rcvTCP(recv_buffer, new_fd, TIMEOUT_SEC) <= 0) {
          logger_errno("recvTCP() error");
        } else {
          current_new_fd = new_fd;
          checkCommand(recv_buffer);
        }
      }
    }
    close(new_fd);
  }
  close(sockfd);
  halt = 1;
  PFVERB("*%10s.......................[OFF]\n", "Server");
  pthread_exit(NULL);