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

c++ - Function signature as a function template parameter -

algorithm - What are some ways to combine a number of (potentially incompatible) sorted sub-sets of a total set into a (partial) ordering of the total set? -

How to call a javascript function after the page loads with a chrome extension? -