소켓 바인드 오류...
안녕하세요. 어제 제가 이상한(?) 경험을 했는데 이 현상이 도무지 이해가 되질 않아서 이렇게 글을 올립니다.
개발환경
서버 : 리눅스 CentOS 5.X, g++ 컴파일러
클라 : WINDOW, Visual Studio 2008
ServerEvtsvr : 5050 포트 TCP 통신을 담당. 평시 accept를 대기하고 있다가 클라이언트가 접속하면 fork() 시켜 Child 프로세스가 생성
ServerPManager : 프로세스가 실행중인지를 감시하여 만약 죽어있으면 ServerEvtsvr를 실행시켜줌.
서버프로그램이 언제나 클라이언트와 연결을 보장하기 위해 프로세스의 실행여부를 체크를 하는 프로그램인 ServerPManager를 만들었습니다. 또, ServerPManager 프로세스가 죽었을때를 대비하여 ServerEvtsvr가 ServerPManager의 실행을 감시하여 ServerPManager 프로그램을 실행하도록 만들었습니다.
그런데 문제는 여기서 시작합니다. ServerEvtsvr 프로세스가 ServerPManager를 실행시키고, 이 ServerPManager가 ServerEvtsvr이 죽었음을 확인하고 다시 ServerEvtsvr를 실행시키면 클라이언트가 접속을 해오지 못합니다.
netstat 로 확인하니 죽기이전 ServerEvtsvr가 Listen 상태에서 자원회수가 일어나지 않습니다. ServerEvtsvr프로세스는 재실행되면서 소켓을 생성하고 바인드할때 바인드 오류가 납니다.
Address already in use 어쩌구...
그래서 서버의 또다른 프로세스 ServerA 에게 ServerPManager를 실행시키게 하니 이런현상은 일어나지 않았습니다. 테스트시 ServerEvtsvr는 Kill 명령을 통해 죽였고, ServerEvtsvr에서 서버소켓을 생성후 SO_REUSEADDR옵션을 주어 bind 시켰습니다.
왜 이런현상이 일어날까요. 어떻게 접근하면 이 현상의 보다 근원적인 문제를 파악할 수 있을까요.
listen 소켓이 공유되어서 생긴 현상
listen 소켓이 공유되어서 생긴 현상 같은데요.(확실히는 모르겠습니다. fork를 잘 쓰질 않아서)
ServerEvtsvr이 ServerPManager를 실행시킬 때 fork후에 자식 프로세스(ServerPManager로 exec계열 함수 호출할)에서 listen 소켓등을 close하고 테스트 해보세요.
이건 제 질문인데 이 질문글 관련하여 검색하다가 다음글을 발견했는데, 나빌레라님 답글이 맞는건가요? (테스트를 해볼까나...)
https://kldp.org/node/1962#comment-424440
Signature :) - "여유를 갖고 행동하되 게을러지지 말자"
댓글 달기