파이톨치

[socket programming] Socket Options 본문

대학수업/socket programming

[socket programming] Socket Options

파이톨치 2024. 4. 19. 02:28
728x90

Socket Options

소켓 옵션을 통해 소켓 함수의 동작을 세밀하게 조정할 수 있다. 소켓 코드와 프로토콜 구현 코드(TCP, UDP, IP)를 세부적으로 제어한다. 

 

int setsockopt(int sock, int level, int optname, const void *optval, socklen_t optlen); 

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

 

level = SOL_SOCKET, IPPROTO_IP, IPPROTO_IPV6, IPPROTO_TCP가 있다. 


SOL_SOCKET 레벨 옵션 

# SO_BROADCAST 

int b = 1; 

setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &b, sizeof(b)); 

 

# SO_KEEPALIVE 

TCP 프로토콜 수준에서 연결 여부 확인을 위해, 주기적으로 TCP 패킷을 보낸다. (2시간 간격). 응답하면 정상 작동, 없으면, 소켓을 닫는다. ACK 패킷으로 정상이라고 응답하는경우, 응용 프로그램에는 어떠한 통보도 하지 않고 커널 간의 확인만으로 상대방이 살아있음을 확인하고 마무리한다. 상대방으로부터 아무런 응답이 없거나 RST 응답을 받으면 소켓을자동으로 종료한다.

setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &b, sizeof(b)); 

 

# SO_LINGER 

close 함수 실행을 지연시킴. 즉시 커널에서 복귀해서 버퍼 확인 불가하다. 이걸 하면 close 할 때, 커널에서 복귀 시점에 송신 버퍼의 자료가 모두 송신 된 것이 확인될 때까지 지연가능.

 

l_linger: SO_LINGER 옵션이 활성화된 경우, close() 호출 시 행동을 지정합니다. 

0이면 close() 호출 시 즉시 반환하고, 남은 데이터는 전송되지 않고 버려집니다. (Hard close) 

0보다 크면 해당 시간(초)만큼 기다립니다. 이 시간 내에 남은 데이터 전송이 완료되면 정상 종료되고, 시간이 초과되면 전송을 중단하고 강제 종료됩니다. (Graceful close)

 

struct linger optval

optval.l_onoff=1; 

optval.l_linger=10; 

setsockopt(sock, SOL_SOCKET, SO_ LINGER, & optval , sizeof( optval )); 

 

shutdown() 함수 참조

 

# SO_SNDBUF & SO_RCVBUF 

소켓의 송신 버퍼와 수신 버퍼 크기 변경함. 입력버퍼의 크기를참조 변경 때에는 SO_RCVBUF, 출력버퍼의 크기를 참조 변경 할 때에는 SO_SNDBUF사용한다.

int optval;

optval *= 2; 

setsockopt(sock, SOL_SOCKET, SO_ LINGER, & optval , sizeof( optval )); 

 

# SO_SNDTIMEO, SO_RCVTIMEO 

용도는 데이터 전송함수가 작업완료와 상관없이 일정 시간 리턴하게

 

# SO_REUSEADDR 

현재 사용 중인 IP 주소와 포트번호를 재사용, 현재 사용 중인 IP 주소와 포트번호를 이용해 bind() 함수를(성공적으로) 호출있음.

TCP 서버 종료재실행bind( ) 함수에서 오류가 발생하는 일을 방지. 여러IP 주소를보유한 호스트에서 같은기능의 서버를 IP 주소 별로 따로 운용 할 있게 함. 멀티캐스팅응 용프로그램이 같은 포트번호를 사용할 있게

 

TCP 서버를 종료한 후 바로 재실행하면, 종종 bind() 함수에서 "Address already in use" 오류가 발생할 수 있습니다. 이는 이전 실행에서 사용된 포트가 아직 운영체제에 의해 점유되어 있기 때문, 이 문제는 TCP의 TIME_WAIT 상태와 관련됨. 이를 방지하기 위해서는 소켓 옵션 중 SO_REUSEADDR를 사용, 이 옵션을 설정하면 TIME_WAIT 상태의 포트도 재사용함. 

 


shutdown() 함수

shutdown() 함수는 close()와 달리 소켓을 완전히 닫지 않고, 지정한 방향으로의 데이터 전송만 중단한다. 

 

일방적인 연결 종료(close)의 문제점

소켓이 소멸되므로 더 이상의 입출력은 불가능, 상대방의 상태에 상관없이 일방적인 종료의 형태, 상대 호스트의 데이터 송수신이 아직 완료되지 않은 상황이라면 문제가생. close 함수가 호출되면 상대호스트(소켓)으로 EOF전달된다. 이는 모든 데이터의 전송이 끝났다는 신호이다. 

 

Half-close (우아한 종료)

수신자 입장에서 종료를 원한다는 것은, 이상 전송할 데이터가 존재하지 않는 상황이다. 상대방도 종료를 원하는지 확인되지 않은 상황이므로, 입력 스트림은 종료시키지 않을 필요가 있다. 때문에 일반적으로 Half-close는 출력 스트림만 종료하는 것을 의미한다.  출력 스트림만 종료를 해도 EOF전달되니, close 함수의 호출을 대체하고도, 상대 호스트의 종료를 기다릴 있다.

 

shutdown(int sock, int howto);

 

SHUT_RD, SHUT_WR(출력 스트림 종료), SHUT_RDWR


time-wait

Time-wait이해

서버, 클라이언트에 상관없이 TCP 소켓에서 연결의 료를 목적으로 Four-way handshaking번째 메시지를 전달하는 호스트의 소켓은 Time-wait 상태친다.클라이언트(또는 서버)가 연결 종료를 위해 FIN 플래그를 설정한 세그먼트를 보내고, 이 과정에서 첫 번째 FIN 메시지를 보낸 호스트의 소켓은 상대방의 ACK와 FIN을 기다리는 상태가 되는데, 이를 TIME_WAIT 상태라 함.  Time-wait 상태 동안에는 해당 소켓이 소멸되지 않아서 할당받은 Port다 른소켓이 할당할 없다. 

 

Time-wait존재이유

왼쪽그림에서 호스트A마지막 ACK소멸되는 황을 대비해서 Time-wait 상태가 필요하다. 호스트A마지막 ACK소멸되면, 호스트B계속해서 FIN 메시지를 호스트A전달하게된다

 

Time-wait필요하다. 그러나 서비스 중인 서버의경우 Time-wait문제가 있다. 그러한 경우에는 Time-wait 태에 있는 Port할당이 가능하도록 코드를 수정해야 한다.

int server_socket = socket(AF_INET, SOCK_STREAM, 0);
int optval = 1;
setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));
bind(server_socket, (struct sockaddr*)&server_addr, sizeof(server_addr));

IPPROTO_TCP 레벨 옵션

TCP_NODELAY 옵션

Nagle(네이글) 알고리즘여부결정, 슬라이딩윈도우를이용하여전송효율높임. 

 

Nagle 알고리즘 

인터넷의과도한트래픽과그로인한송속도의저하를막기위해서디자인알고리즘이Nagle 알고리즘이다.이러한Nagle 알고리즘은목적이확한경우가아니면중단하지말아야, 소켓은기본적으로Nagle 알고리즘적용해서데이터를송수신한다. Nagle 알고리즘은앞서전송한데이터에대한ACK 메시지를받아야만, 다음데이터를전송하는알고리즘이다 

 

Nagle 알고리즘의동작방식

보낼데이터가MSS정의된크기만큼쌓이면상대편에무조건보냄

보낼데이터가MSS보다작으면이전에보낸데이터에대한ACK오기를기다림. ACK도착하면보낼데이터가MSS보다작더라도상대편에보냄

 

Nagle 알고리즘의장단점

장점: 작은패킷이불필요하게많이생성되는일을방지해네트워크트래픽을감소시킴

단점: 데이터가충분히쌓일때까지또는ACK도달할때까지대기하는시간때문에응용프로그램의반응시간이길어질있음. 이를피하기위해서는TCP_NODELAY 옵션을enable 해야

 

 



 

 

728x90