c - "bind: address already in use" even with SO_REUSEADDR set -


i've written simple echo server, includes following line:

int yes = 1; if (setsockopt(socketfd, sol_socket, so_reuseaddr, &yes, sizeof(int)) == -1) {     perror("setsockopt");     exit(1); } 

however despite this, i'm still getting error when try call bind on socket i've used. in fact, i'm getting error if try call bind on socket i've used in program, period, if it's not recent - they're not being cleared kernel or something. there else have do?

here's full code:

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netdb.h> #include <arpa/inet.h> #include <unistd.h>  void preparehints(struct addrinfo *hints, int tcp_udp) {     memset(hints, 0, sizeof(struct addrinfo));     hints->ai_family = af_unspec;     hints->ai_socktype = (tcp_udp == 1) ? sock_stream : sock_dgram;     hints->ai_flags = ai_passive; /* autofill ip */ }  void writesocket(int fd, const char *msg) {     size_t nbytes = 0;     size_t len = strlen(msg);     while (nbytes < len)         nbytes += send(fd, msg, len, 0); }  void waitloop(int sockfd) {     int clientfd, nbytes;     struct sockaddr addr;     socklen_t len;     char buf[512];     while(1) {         clientfd = accept(sockfd, &addr, &len);         if (clientfd < 0) {             perror("accept");             exit(1);         }         while ((nbytes = recv(clientfd, buf, 512, 0)) != eof) {             buf[nbytes] = '\0';             strcat(buf, "\r\n");             writesocket(clientfd, buf);         }         close(clientfd);     } }  int main(int argc, char **argv) {     const char *port = (argc >= 2) ? argv[1] : "7474";     struct addrinfo hints, *res;     preparehints(&hints, 1);      int status = getaddrinfo(null, port, &hints, &res);     if (status != 0) {         printf("error on getaddrinfo\n");         exit(1);     }      /* scan through sockaddr's returned getaddrinfo until set socket 1 */     int socketfd;     struct addrinfo *cur;     (cur = res; cur != null; cur = cur->ai_next) {         if ((socketfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) >= 0)             break;     }     /* make sure found 1 */     if (socketfd == -1) {         printf("error on socket\n");         exit(1);     }     /* bind socket struct sockaddr_in contained in res */     int bindres = bind(socketfd, cur->ai_addr, cur->ai_addrlen);     if (bindres != 0) {         perror("bind");         exit(1);     }      int yes = 1;     if (setsockopt(socketfd, sol_socket, so_reuseaddr, &yes, sizeof(int)) == -1) {         perror("setsockopt");         exit(1);     }      if (listen(socketfd, 5) < 0) {         printf("error on listen\n");         exit(1);     }      printf("success, listening on socket %d, port %d\n", socketfd, ntohs(((struct sockaddr_in *)res->ai_addr)->sin_port));     waitloop(socketfd);     return 0; } 

you setting so_reuseaddr after calling bind(). need set before binding, not after.


Comments

Popular posts from this blog

Perl - how to grep a block of text from a file -

delphi - How to remove all the grips on a coolbar if I have several coolbands? -

javascript - Animating array of divs; only the final element is modified -