Below is abstract code of something like a daemon. I need to check if my daemon is already here (if yes, I exit). Then I close the bound socket, do some forks (they will live after the daemon is restarted, so I don't want them having my bound socket).
int is_me_here()
{
int sck = socket(AF_INET, SOCK_STREAM, 0), temp=1;
struct sockaddr_in addr;
addr.sin_port = htons(1234);
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
bzero(addr.sin_zero, 8);
//setsockopt(sck,SOL_SOCKET,SO_REUSEADDR,&temp,sizeof(int)); // #1 HERE?
if ((bind(sck, (struct sockaddr *)(&addr), sizeof(struct sockaddr_in))) < 0){
printf("cannot bind. My daemon is already here\n");
return -1;
}
close(sck);
return 0;
}
void foo(){
int sck = socket(AF_INET, SOCK_STREAM, 0), temp=1, new_sockfd;
struct sockaddr_in addr, cliaddr;
addr.sin_port = htons(1234);
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
bzero(addr.sin_zero, 8);
//setsockopt(sck,SOL_SOCKET,SO_REUSEADDR,&temp,sizeof(int)); // #2 HERE?
if ((bind(sck, (struct sockaddr *)(&addr), sizeof(struct sockaddr_in))) < 0){
printf("WTF\n");
return;
}
listen(sck, 5);
socklen_t lenaddr = sizeof(struct sockaddr_in);
while(1){
if ((new_sockfd = accept(sck, (struct sockaddr *)(&cliaddr), &lenaddr)) == -1){
sleep(1);
continue;
}
// ...
close(new_sockfd);
}
}
int main()
{
if (is_me_here() < 0)
return 0;
// some forks. Dont wanna them having the socket binded.
foo();
return 0;
}
As I know, the kernel keeps bound sockets in TIME_WAIT. So, I need to use SO_REUSEADDR to bind again after the forks. But, where is the right place to apply SO_REUSEADDR? Will the kernel keep my socket in TIME_WAIT after is_me_here()? I don't listen() or accept() something.
P.S. on my system, and some other systems, the code works fine wherever I set the SO_REUSEADDR. But I am afraid that some another system will give me an error in bind() in foo().
You have to set the flag to an int, pass the pointer and the size of the flag.
You can use SO_REUSEADDR on both UDP and TCP sockets, right after you create the socket.