2016년 6월 10일 금요일

뇌자극 TCP_IP 프로그래밍 20강 요약

20강 소켓 옵션

1. 소켓 옵션 변경 함수

현재 설정 값을 가져오는 함수 / 값을 설정하는 함수

#include <sys/types.h>
#include <sys/socket.h>

int getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen);
int setsockopt(int s, int level, int optname, void *optval, socklen_t *optlen);

s : 설정 값을 가져오거나 설정할 소켓 지정 번호
level : 선택할 수 있는 영역은  SOL_SOCKET, IPPROTO_TCP, NSPROTO_IPX 가 있다.
optname : 변경할 옵션 이름을 가리키는 값이다. level에 따라서 서로 다른 값을 지정할 수 있다.
optval : 해당 옵션의 값을 지정한다.
optlen : 옵션에 따라 optval 은 다양한 크기를 가질 수 있다. optlen으로 optval 값의 크기를 지정한다.

소켓 옵션의 이름(optval)

SOL_SOCKET 영역

SO_REUSEADDR : 소켓 주소 지원을 재사용
SO_SNDBUF : 소켓 쓰기 버퍼의 크기 조정
SO_RCVBUF : 소켓 읽기 버퍼의 크기 조정
SO_LINGER : 소켓 종료 방식의 조정

IPPROTO_TCP 영역

TCP_NODELAY : Nagle 알고리즘의 사용

예제)
int buf_size = 0;
int opt_len;

opt_len = sizeof(int);
//읽기 소켓 버퍼의 크기를 읽어온다.
getsockopt(sockfd, SOL_SOCKET, SO_REVBUF, (void *)&buf_size, &opt_len);

//읽기 소켓 버퍼의 크기를 512 바이트 크기로 설정한다.
buf_size = 512;
setsockopt(sockfd, SOL_SOCKET, SO_REVBUF, (void *)&buf_size, sizeof(int));

소켓 옵션은 루트 권한으로만 변경 가능하다.

2. 소켓 버퍼 설정

소켓 옵션을 이용해서 소켓 버퍼의 크기를 변경할 수 있다.

//읽기 소켓 버퍼의 크기를 1024 바이트 크기로 설정한다.
buf_size = 1024;
setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, (void *)&buf_size, sizeof(int));

슬라이딩 윈도우

TCP는 한번에 전송할 수 있는 최대 세그먼트 크기가 정해져 있다.
이를 TCP MSS(Maximum Segment Size) 라고 한다.
MTU는 한번에 보낼 수 있는 패킷의 크기로 IP 기반의 정보이고
MSS는 TCP 기반의 크기 정보다.

TCP 는 슬라이딩 윈도우라는 기법을 사용한다.
창의 크기를 크게 해서 여러 패킷을 논리적인 하나의 패킷으로 묶어서 처리하는 방식이다.
이 창의 크기를 윈도우 크기라고 한다.

//쓰기 소켓 버퍼의 크기를 2048KB로 설정한다
int buf_size = 2048;
getsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, (void *)&buf_size, sizeof(int));

일반적으로 윈도우 크기는 기본 설정된 윈도우 크기를 그대로 이용한다.

3. 우아한 연결 종료

TCP는 세션을 맺기 위해서는 세 번의 패킷 교환이 필요하며
이를 Three wasy handshake 라고 한다.
서버와 클라이언트 완전한 통신 종료는 네 번의 패킷 교환이 필요하다
우아한 연결 종료란 네 번의 패킷 교환이 성공적으로 이루어진 상태를 의미한다.

TCP 연결 상태
연결 대기 상태(LISTEN), 정상 연결 상태(ESTABLISHED), 연결 종료 중인 상태(TIME WAIT)

4. 소켓 재사용

소켓은 OS에서 관리하는 자원으로 시스템 전체에 거쳐서 유일해야 한다.
소켓의 유일함은 인터넷 주소와 포트 번호로 결정된다.

소켓 프로그램은 우아한 종료를 위해서 TIME_WAIT 상태에 놓인다
TIME_WAIT 상태로 기다리는 기간은 보통 1~4분 정도인데
이 시간 동안 해당 주소와 포트를 이용할 수 없다.

서버가 TIME_WAIT 상태에 놓여있다면 새롭게 추가 실행하는 서버는
bind 함수의 호출에서 에러가 발생한다.
SO_REUSEADDR 옵션을 이용하면 기존의 소켓 자원을 재사용함으로써,
서버를 바로 실행시킬 수 있다.

예제)
int optval = 1;
listen_fd = socket();
setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));

5. Nagle 알고리즘

반응 속도와 대역폭 사이에서 최적의 값을 찾아준다.
소켓은 기본적으로 Nagle 알고리즘을 이용해서 데이터를 전송한다.
Nagle 알고리즘은 대역폭을 효과적으로 사용할 수 있도록 도와주지만
반응 속도를 희생 시킨다.
TCP_NODELAY 소켓 옵션을 이용해서 Nagle 알고리즘을 끄거나 킬 수 있다

int iptval = 1;
listen_fd = socket();
setsockopt(listen_fd, IPPROTO_TCP, TCP_NODELAY, &optval, sizeof(optval));

이번 것은 옵션 조정하는 것이기에 소스 코드는 없다.

댓글 없음:

댓글 쓰기