본문 바로가기
IT 이론/네트워크&무선통신

소켓의 다양한 옵션

by 지식id 2013. 6. 15.
반응형

소켓은 그냥 정해진 함수 3~4개만 쓰면 사용 할 수 있는 편한 것이라고들 인식하지만, 사실 더 깊게 들어가면 정말 다양한 옵션들이 있다. 일반적으로 간단한 데이터 송수신 정도의 프로그래밍에서는 아무것도 건들일 필요 없이 그대로 쓰면 되지만 점점 고급 프로그래밍을 하게 되면 그 특성에 맞기 옵션들을 조작 해 줘야 한다.

(조작 안해도 사용 할 수 있지만 조작 해 주면 더 좋은 성능이 나고, 프로그래밍하기도 편해진다.)

 

소켓의 옵션은 아.주. 많지만 일단 자주 사용되는 몇 가지만 뽑아 보자면 아래와 같다.

 

 Protocol Level 

 Option Name 

 설명

 Get

Set

 SOL_SOCKET

 SO_SNDBUF

 SO_RCVBUF

 SO_REUSEADDR

 SO_KEEPALIVE

 SO_BROADCAST

 SO_OOBINLINE

 SO_ERROR

 SO_TYPE

 송신 버퍼 크기

 수신 버퍼 크기

 지역주소의 재사용 허용

 주기적으로 TCP 연결상태 확인

 브로드캐스트 데이터그램 허용

 OOB데이터 리드

 소켓별 에러 코드를 가져옴

 소켓 유형

 O

 O

 O

 O

 O

 O

 O

 O

 O

 O

 O

 O

 O

 O

 X

 X

 IPPROTO_IP

  IP_TTL

 IP_MULTICAST_TTL

 IP_MULTICAST_LOOP

 IP_MULTICAST_IF

 Time To Live 변경

 멀티캐스트 패킷의 TTL 변경

 멀티캐스트 패킷의 loopback 허용

 멀티캐스트 패킷 인터페이스 지정

 O

 O

 O

 O

 O

 O

 O

 O 

 IPPROTO_TCP

 TCP_KEEPALIVE

 TCP_NODELAY

 TCP_MAXSEG

 TCP keep alive 시간 간격 지정

 Nagle 알고리즘 사용 여부

 TCP 최대 세그먼트 지정

 O

 O

 O

 O

 O

 O

 

보면 계층별로 여러 옵션들이 구분 되어 있는걸 확인 할 수 있다.

이걸 절대 다 외울 필요는 없다. 그냥 소켓 프로그래밍을 공부하다 보면 자연스럽게 알게 되는 것도 많다. 이런걸 하고 싶은데 어떻게 하는지 몰라서 구글링을 하고 예제를 찾아보면 "일단 이 옵션을 이렇게 변경하시구요, ...어쩌고 저쩌고." 라는 내용을 마딱들이게 된다. 그러다 보면 이제 "소켓은 이럴때 이렇게 밖에 할 수 없던데.. 이걸 변경하는 옵션이 있지 않을까?" 라는 의문이 자연스럽게 생길 것이고, 그때마다 찾아 보면 되는 것이다.

 

현재 옵션을 보려면 getsockopt, 옵션을 변경 하려면 setsockopt 함수를 쓴다.

 

위 표를 보면 모든 소켓의 옵션이 변경 가능한 것이 아니란 걸 알 수 있다. 대부분은 get, set 둘다 가능하지만 둘 중에 하나만 가능한것도 드물게 있다.

 

구질구질한 설명은 생략 하자면.. 위 두 함수는 아래와 같이 쓴다. 아래 예제는 mysock이라는 소켓의 Send Buffer크기를 변경하고 확인하는 예제이다.

 

  1. sbuf = 10 & 1024;
  2. optlen = sizeof(sbuf);
  3.  
  4. state = setsocket(mysock, SOL_SOCKET, SO_SNDBUF, (void*)&sbuf, &sizeof(sbuf));
  5. if(state) {
  6.     printf("error"); //적절한 에러 핸들링이 필요함
  7.     exit(1);
  8. }
  9. state = getsockopt(mysock, SOL_SOCKET, SO_SNDBUF, (void*)&sbuf, &optlen);
  10. if(state) {
  11.     printf("error");
  12.     exit(1);
  13. }
  14.  
  15. printf("SEND BUF SIZE : %d\n", sbuf);

두 함수는 모두 실패시 -1, 성공시 0을 반환한다. 어떤 파라미터가 들어가는지는 보면 대충 이해가 갈것이다. 모르면 검색ㄱㄱ

 

했는 김에 변경할 일이 많은 몇몇 옵션들에 대해 살펴보자.

 

SO_REUSEADDR

이 옵션은 이름만 봐도 알 수 있듯이 SOL_SOCKET계층에 있는 옵션이다. 이 옵션은 binding error를 방지하기 위해 변경해 줘야 할 때가 있다. 서버에서 연결을 급하게 끊었다가 다시 연결해야 될 일이 생길 경우 bind() error라고 뜨며 연결이 안된다.

이는 서버에 종료명령을 내렸더라도 마지막 데이터의 전송이 실패 했을때는 대비하여(FIN와 ACK의 전송 확인) socket에서 서버의 접속을 일정 시간동안 유지시켜 두기 때문이다. 이를 Time-Wait라고 하는데, 어떻게 보면 필수적인 것이지만 아까 설명 했듯이 연결을 끊었다가 다시 해야 될 일이 생긴다면 골치 아픈 현상이 아닐 수 없다.

 

이때 setsockopt 함수를 이용해 SO_REUSEADDR 값을 1로 변경하면 Time-Wait상태에서도 서버의 재시작이 가능해 진다.

 

  1. option = true;
  2. optlen = sizeof(option);
  3.  
  4. state = setsocket(mysock, SOL_SOCKET, SO_SNDBUF, (void*)&option, optlen);
  5. if(state) {
  6.     printf("error"); //적절한 에러 핸들링이 필요함
  7.     exit(1);
  8. }

 

TCP_NODELAY

이번에는 IPPROTO_TCP 계층에 있는 옵션이다. 이 옵션은 여러 관련 이론들을 알고 있어야 한다. 지나칠 정도로 요약을 하면, TCP 방식에서의 비효율성을 개선하기 위해 나온 Sliding Window라는 방식이 특정 상황에서 Silly Window라는 Thrashing을 발생시키므로 이를 해결 하기 위해 Nagle Algorithm이 나왔다.

 

Sliding Window와 Silly Window는 포스팅 한개에서 따로 언급 해야 될 만큼 내용이 많으므로 설명은 생략하겠다. 구글링 해 보면 많이 나온다. Nagle알고리즘에 관하여 간단히 설명 하자면

한번에 전송되는 데이터의 양이 작을 때 매번 패킷에 담아 보내려고 하면 패킷에 기본적으로 포함된 헤더정보의 용량보다 데이터의 용량이 더 작은 경우가 발생한다. 이런 비효율적인 상황을 방지하기 위해 Nagle알고리즘은 ACK를 받는 시간동안 buffer에 다음에 송신할 데이터를 충분히 축적 해 두고, 양이 어느정도 되면 송신을 하는 방식이다.

 

이는 트래픽을 줄이는데는 도움이 되지만 속도는 느려지는 방식이라고 할 수 있다. 예전에는 송신측이나 수신측에서 데이터 처리 속도가 느려서 Nagle알고리즘이 필수적이었지만 요즘은 인터넷 속도도 빠르고 대용량 파일 전송이 잦기 때문에 Nagle알고리즘이 오히려 악영향만 미치는 경우도 발생한다. 그렇다고 무조건 Nagle알고리즘을 사용하지 않기엔 서버 상태가 안좋아서 속도가 느려지면 또 Silly Window현상이 발생하여 트래픽이 과도하게 발생 할 수 있기에 적절하게 Nagle알고리즘의 사용 여부를 결정하여야 한다.

 

이를 위한 옵션이 바로 TCP_NODELAY이다. 위 글을 잘 읽었다면 왜 이름이 NODELAY인지 알것이다. Nagle알고리즘이 기본적으로 딜레이를 두고 버퍼에 데이터를 쌓아뒀다가 보내는 메커니즘이기 때문이다. 즉 TCP_NODELAY를 true로 하면 Nagle알고리즘이 off 되는 것이다.

 

보통 Nagle알고리즘을 사용하지 않더라도 트래픽의 증가가 심하지 않은 경우, 그러면서 속도의 증가는 큰 경우에는 Nagle알고리즘을 끄는 것이 맞다. 주로 대용량 파일 전송시에 해당된다.

 

이제는 setsockopt가 익숙할 것이다.

 

int opt_val = 1;

setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void*)&opt_val, &opt_len);

 

반응형

'IT 이론 > 네트워크&무선통신' 카테고리의 다른 글

History of Cellular Systems  (0) 2013.10.17
인터넷 통신 정리  (0) 2013.06.15
Internet transport protocols : TCP and UDP  (0) 2013.04.17
인터넷 계층  (0) 2013.04.17
Delay in packet-switched networks  (0) 2013.04.17

댓글