프로그램

TIME_WAIT 없애기...

고요한하늘... 2007. 5. 14. 14:19

서버와 클라이언트의 빈번한 접속의 흔적인 TIME_WAIT ...

이로 인해 새로운 클라이언트의 접속이 방해되는 경우가 있다.(물론 TIME_WAIT 는 지극히 정상적인 현상이다)

 

이럴때 TIME_WAIT를 회피하는 방법으로

struct linger ling;

 

ling.l_onoff = 1;
ling.l_linger = 0;

setsockopt(socketfd, SOL_SOCKET, SO_LINGER, &ling, sizeof ling );

 

 

TCP는 4-WAY Hand shaking 과정을 거쳐 종료를 하게 된다.

 

                      A <------------------> B ( data proessing )

                                          ...

                  A   -------FIN-------> B

                  A <-------ACK------   B( CLOSE WAIT )

                  A <-------FIN-------   B

(TIME_WAIT )A   -------ACK------> B

 

라고 했을때

 

1. A가 종료하기 위해 B에게 FIN(이제 전 종료합니다) 을 전달한다.

2. 그러면  B는 CLOSE_WAIT로 변경이 되고 잘 받았다는 뜻으로 ACK(알았습니다)를 A에 날린다

3. 그리고 B역시 종료준비가 끝나면 A에게 나역시 종료한다는 의미로 FIN(이제 저도 종료합니다)을 A에 날린다.

4. A역시 FIN을 잘 받았다는 의미에서 B에게 ACK를 날린다.

 

그런데 여기서 4번이 실행되는 동안 A가 바로 문제의 TIME_WAIT상태가 되는것이다.

 

TIME_WAIT에 들어가는 이유는 B가 보낸 FIN을 A가 잘 받았지만 B의 종료는 A에서 전달한 ACK이 전달되고 나서야 가능하다. 만약 B에 A가 보낸 ACK이 전달되지 않으면 B는 다시 A에게 FIN을 보내게 된다. 이런 경우는 대비해서 A에서 충분한 시간동안 B를 기다려 주어야 하기 때문에 발생한다.

 A가 B에게 보낸 메세지는 모두 잘 받았고 종료해도 된라고 보낸 메세지가 B에게 전달되었는지 알수 없고, 혹시 전달이 되지 않아 B가 다시 A에게 FIN( 이제 저도 종료합니다 )보낼때를 대비해 일정 시간 동안 TIME_WAIT 상태에 놓이게 된다. 보통 A를 서버 B를 클라이언트로 보면 될것 같다.

 

서버가 TIME_WAIT 상태에 놓이게 되면 소켓 재사용에 문제가 발생할수 있다. ( 클라이언트의 경우는 정상적인 종료상황이다. )

따라서  클라이언트에서 명시적으로 소켓을 종료해야 서버가 TIME_WAIT상태에 놓이는 것을 방지할수 있다.


보통의 경우 먼저 종료하고자 하는 쪽에서 TIME_WAIT 상태에 놓이게 된다.


커널 옵션을 통해 소켓을 재사용 하고자 한다면

/etc/sysctl.conf에

tcp_tw_reuse = 1 를 추가하고

# 0은 재사용 안함

# 1은 재사용 허용

적용을 위해

sysctrl  -p 를 실행시킨다




'프로그램' 카테고리의 다른 글

영어 관련  (0) 2007.09.07
lex yacc  (0) 2007.08.08
주소줄 검색 , 주소창 두개  (0) 2007.05.12
0!3*4Y6s869Y;g 터미널에서 한글이 깨질때  (0) 2007.04.20
굿데이(goodday) 툴바 제거 방법  (0) 2007.04.14