서버 프로그램을 강제로 Control+C키를 눌러 종료시킨 후, 재 실행시키면 Bind가 되지 않는 문제가 발생하였다.
어느정도 시간이 되면, 다시 Bind가 되긴 하지만, 1초라도 쉬고 있으면 안되는 데몬역할을 수행할 프로그램이었기에, 반드시 해결해야 되는 문제였다.
예전에 머드 서버 프로그램을 작업할 때, 본 기억이 있었는데... 기억이 가물가물 -_-;;;;;;
"Address already in use"
TCP로 통신을 할 때는 "TIME-WAIT"라는게 존재한다고 한다.
데이터가 완전히 전송되지 않았는데, 통신이 끊어지는 것을 막기위한 방법이라고 하는데, 자세한 내용은 "TIME-WAIT"로 검색해보면 될듯...
Linux에서 "TIME-WAIT"의 디폴트 시간은 45초이다. 따라서, 서버 데몬이 죽은후 45초가 경과하면 다시 데몬을 실행시킬 수가 있는 것인데, 데몬이 죽은 경우 바로 데몬을 띄워주기 위해서는
#include <sys/types.h>
#include <sys/socket.h>
int getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen);
int setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen);
RETURN VALUE
On success, zero is returned. On error, -1 is returned, and errno is set appropriately.
ERRORS
EBADF The argument s is not a valid descriptor.
ENOTSOCK
The argument s is a file, not a socket.
ENOPROTOOPT
The option is unknown at the level indicated.
EFAULT The address pointed to by optval is not in a valid part of the process address space. For getsockopt, this error may also be
returned if optlen is not in a valid part of the process address space.
EINVAL optlen invalid in setsockopt
#include <sys/socket.h>
int getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen);
int setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen);
RETURN VALUE
On success, zero is returned. On error, -1 is returned, and errno is set appropriately.
ERRORS
EBADF The argument s is not a valid descriptor.
ENOTSOCK
The argument s is a file, not a socket.
ENOPROTOOPT
The option is unknown at the level indicated.
EFAULT The address pointed to by optval is not in a valid part of the process address space. For getsockopt, this error may also be
returned if optlen is not in a valid part of the process address space.
EINVAL optlen invalid in setsockopt
setsockopt(
Socket,
SOL_SOCKET,
SO_REUSEADDR , <--- 바로 요놈!
&optval, <- Default : 0
sizeof(optval)
);.
SO_REUSEADDR을 사용하여 주면, 데몬이 죽은 후 45초가 경과하지 않더라도 바로 Bind를 할 수 있게 된다. 디폴트 값이 0인데, 이걸 1로 바꿔주면 바로바로 소켓에 주소가 할당되고 또 사라졌다가 다시 할당된다.