본문 바로가기
프로그래밍/리눅스 시스템 & 네트워크-소켓

[SOCKET]TCP KEEPALIVE 옵션 설정

by Noritorgigi 2013. 8. 29.
728x90

TCP의 경우, connection oriented protocol이지만, 송수신 중, 상대방 프로세스가 종료되는 등 정상적인 상황이 아닌 경우에는 세션의 종료 여부를 감지할 수 없다. 단지, 송신 측 TCP 버퍼가 가득 찬 경우에 EAGAIN을 발생시킬 뿐이다.

다시 말해, LAN 케이블이 뽑힌다든지, 기타 비정상적인 종료가 있을 경우, 상대 측에서 감지할  수 없다는 것이다.

TCP option 중, SO_KEEPALIVE라는 옵션이 있는데, setsockopt 함수에서 SO_KEEPALIVE를 1로 setting하면 소켓 내부적으로 일정시간 간격으로 heartbeat을 전송하여, 비정상적인 세션 종료에 대해 감지한다. 그런데 SO_KEEPALIVE를 설정할 경우, 시스템에서 설정한 시간 간격으로 세션을 체크하게 되는데 이 시간이 꽤 길다.(보통 2시간정도)

세부 시간 설정에 관한 값은 /etc/sysctl.conf에서 확인할 수 있다.

시스템 설정 시간 간격 외에 세션 별로 해당 값들을 설정할 수 있다.

설정할 수 있는 설정 종류는 다음 표와 같다.

<KEEPALIVE 관련 옵션 및 설명>

옵션 종류  옵션 값 및 의미 소켓 레벨 
SO_KEEPALIVE 1 (KEEPALIVE ON)
0 (KEEPALIVE OFF)
SOL_SOCKET
TCP_KEEPIDLE  최초에 세션 체크 시작하는 시간 (단위 : sec) SOL_TCP
TCP_KEEPCNT 최초에 세션 체크 패킷 보낸 후, 응답이 없을 경우 다시 보내는 횟수 (단위 : 양수 단수의 갯수) SOL_TCP
TCP_KEEPINTVL TCP_KEEPIDLE 시간 동안 기다린 후, 패킷을 보냈을 때 응답이 없을 경우 다음 체크 패킷을 보내는 주기 (단위 : sec) SOL_TCP

 

<사용 예>

⊙ keepAlive 설정 관련하여 간단한 함수를 구현한 것이다. 여기서 sockFd는 connect하는 client socket 혹은 server쪽은 listen socket이 아닌 accept한 socket에 대해 설정하면 된다. 

 

<예제 코드>

int tcpSetKeepAlive(int nSockFd_, int nKeepAlive_, int nKeepAliveIdle_, int nKeepAliveCnt_, int nKeepAliveInterval_)
{
     int nRtn;

     nRtn = setsockopt(nSockFd_, SOL_SOCKET, SO_KEEPALIVE, &nKeepAlive_, sizeof(nKeepAlive_));
     if(nRtn == -1)
    {
         pr_err("[TCP server]Fail: setsockopt():so_keepalive");
         return -1;
     }

     nRtn = setsockopt(nSockFd_, SOL_TCP, TCP_KEEPIDLE, &nKeepAliveIdle_, sizeof(nKeepAliveIdle_) );
     if(nRtn == -1)
     {
          pr_err("[TCP server]Fail: setsockopt():so_keepidle");
          return -1;
     }

     nRtn = setsockopt(nSockFd_, SOL_TCP, TCP_KEEPCNT, &nKeepAliveCnt_, sizeof(nKeepAliveCnt_) );
     if(nRtn == -1)
     {
          pr_err("[TCP server]Fail: setsockopt():so_keepcnt");
          return -1;
      }

     nRtn = setsockopt(nSockFd_, SOL_TCP, TCP_KEEPINTVL, &nKeepAliveInterval_, sizeof(nKeepAliveInterval_) );
     if(nRtn == -1)
     {
          pr_err("[TCP server]Fail: setsockopt():so_keepintvl");
          return -1;
      }
     return nRtn;
}

 

 

728x90