소켓어드레스 재사용 문제
예전에도 이런 질문이 있었던거 같은데요.
다시 한번 확인하구 싶어서요.
Socket 어드레스라 함은 (IP_number, Port_number)이구요.
Socket서버프로그램과 소켓클라이언트 프로그램을 같은 Machine에서 수행하구
나서 두개의 프로그램을 돌리고 나서..
netstat -a | grep Port_number 하면
TIME_WAIT라는 state가 남구요.
TIME_WAIT가 남아있는 Local Port(Client가 사용한 emphermal port) 에
대해서 bind함수를 수행하면(서버에서)
"already in use"라는 메시지가 나오는 며, socket bind를 못하는 데..
위의 문제를 해결하기 위하여
int optvalue=1;
setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&optvalue,sizeof(optvalue)
위와 같은 식으로
여하튼 Client에두 이 옵션을 사용해야 하구 서버에두 이 옵션을 사용하니까
TIME_WAIT가 남아 있는 소켓어드레스에 대해서두 bind가 되는군요.
(1)이렇게 양쪽다 옵션을 설정해줘야 되는 건가요?
이 옵션을 사용하지 않는다면
TIME_WAIT가 없어지기 전까지 인내심이 부족하다면
TIME_WAIT란 TCP state를 최소화하기 위해서는
/proc/sys/net/ipv4 디렉토리의 TCP/IP 커널 value를 고쳐서 부팅하구
사용하면 되는 거 같은데...
(2)사용해보지 않아서 잘모르겠는데 맞는 지 모르겠군요?
(3) 글구 혹시 SO_REUSEADDR 이 어느 헤더파일에 있는 지 아세요?
Linux에선 SO_REUSEPORT가 먹지 않던데...
예전에 Digital Unix에서 소켓서버 프로그램을 짜놓은게 있는 데..
가끔 소켓서버 프로그램을 종료시키고 나서 바로 다시 재가동할려구 하면
아직두 소켓어드레스에 대해 여러 TCP state가 남아있어서
"already in use"라는 메시지가 나오며 실행이 안되서 약 2분 가량 있다가
TCP State가 모두 없어진 다음에 실행을 하곤 했던 기억이 나서..
요즈음 다시 그 문제를 해결하기 위해 Linux를 이용해서 테스트 해보려구
하는 데...
Digital UNIX에서 TIME_WAIT설정시간을 바꾸는 그런 툴이 있는 것 같은데..
(솔라리스에은 ndd라는 것이 있는 거 같은데..) 원격에 있어서 확인할수도 없고..
여하튼 Client쪽에서 setsockopt같은 API를 사용하지 못하는 경우
(무선 IWF방식 같은 경우)
서버쪽에서 TCP state가 남은 소켓어드레스에 대한 재사용을 가능하게 하는
방법이 있는 지 모르겠네요?
제가 테스트를 잘못한건지 모르겠네요.
고수님들의 조언 부탁드립니다.
Re: 소켓어드레스 재사용 문제
packet이 늦게 도착해서 생기는 오동작을 방지하기 위해서 있는 것이죠.
아뇨 서버쪽에서만 해주면 됩니다. socket을 만들고 bind 하기전에 해주면 되죠.
아닙니다. kernel 값이 아니라 TIME_WAIT 을 조절하는 SO_LINGER 값을 고쳐주면 됩니다. 다음은 lingering을 0 초로 하는 예입니다.
위와 같이 접속후에, 서버쪽에서는 accept 후에 setting해주면 됩니다.
/usr/include/asm/socket.h 에 구현 있죠.
#include <sys/socket.h> 을 통해 include 될것입니다.
Linux에서는 아직 SO_REUSEPORT가 구현이 안되어 있습니다.
최근 버전에서는 되었는지 모르겠는데, 제가 아는 한은 구현이 안되어 있구요.
테스트 해보시고.. 안되시면 답장주세요..
---
http://coolengineer.com
감사합니다.
님의 답변에 많은 도움이 되었습니다. :P :P
소켓어드레스 reuse는 서버 쪽에서만 셋팅해주면 될 것 같았는데..
제가 테스트하는 환경이 한대의 Machine내에서 server와 client를 돌리다
보니까.. server 나 client를 kill해도..
server의 Local port에 대한 state를 남길 수가 없어서..
임시로 TIME_WAIT 가 남아있는 client의 local port를 다시 server의
local port로 사용해서 테스트하다보니까 그렇게 되었네요...
예전 개발환경이 서버의 특정 Port 에 remote의 client가 동시에 100개 이상이 접속하는 환경에서 서버 프로세스(parent)를 kill하면
서버의 Local Port에 대한 TIME_WAIT는 물론 ..FIN1, .. FIN2,.. 기타
TCP의 state가 남아서...
이런 똑같은 환경을 한대의 Machine에서 구현하구 테스트하려고 하니
잘 안되네요..
나머지 부분은 테스트해보구 글 올리겠습니다.
앞으로 좋은 글 부탁드립니다.
댓글 달기