Bind(): address already in use
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:
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:
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); |