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
'프로그래밍 > 리눅스 시스템 & 네트워크-소켓' 카테고리의 다른 글
setsockopt - IP_MULTICAST_TTL (0) | 2014.06.12 |
---|