I wrote a simple echo server that includes the following line:
int yes = 1; if (setsockopt(socketfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) { perror("setsockopt"); exit(1); }
However, despite this, I still get an error when I try to call bind on a socket that I recently used. In fact, I get this error if I try to call bind on the socket that I used in this program, period, even if it is not the last, as if they are not cleared by the kernel or something like that. Is there anything else I should do?
Here is the 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 returned by getaddrinfo until we successfully set up a socket with one */ int socketfd; struct addrinfo *cur; for (cur = res; cur != NULL; cur = cur->ai_next) { if ((socketfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) >= 0) break; } /* make sure we actually found one */ if (socketfd == -1) { printf("Error on socket\n"); exit(1); } /* bind the socket to the 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; }