Public/tip & tech

[TCP/IP 소켓 프로그래밍] 9. 소켓의 다양한 옵션

quantapia 2009. 8. 14. 10:47

9-1 소켓의 옵션

1. 소켓의 옵션 조작 : 소켓의 기본적인 특성(다양함)을 변경하는 것.

※ 운영체제에 의해 관리. 운영체제는 소켓의 특성에 대한 정보를 보관하고 있다.

2. 소켓의 기본적인 특성

 - 입력 및 출력 버퍼의 크기

 - 데이터 전송 방식(TCP 또는 UDP)

 - TTL(Time To Live) : 건너뛸 수 있는 라우터의 개수. hop과 관련됨.

3. 옵션은 대부분 변경(set) 가능하지만 참조(get)만 가능한 것도 있다.


소켓의 옵션 관련 함수

1. 현재 설정 상태 정보를 가져오는 함수.

#include <sys/types.h>

#include <sys/socket.h>

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

sock : 소켓을 나타내는 디스크립터

level : 확인할 옵션의 프로토콜 레벨

optname : 확인할 옵션의 이름

optval : 원하는 옵션의 이름의 값을 얻음.

optlen : optval 포인터가 가리키는 버퍼의 크기.


#include<winsock2.h>

int getsockopt(SOCKET s, int level, int optname, char FAR *optval, int FAR *optlen);

s : 소켓 핸들


2. 옵션을 변경하는 함수.

#include<sys/types.h>

#include<sys/socket.h>

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

sock : 소켓을 나타내는 디스크립터

level : 변경할 옵션의 프로토콜 레벨

optname : 변경할 옵션의 이름

optval : 원하는 옵션의 값을 저장한 포인터 전달.

optlen : optval 포인터가 가리키는 버퍼의 크기.


#include<winsock2.h>

int setsockopt(SOCKET s, int level, int optname, const char FAR * optval, int optlen);

s : 소켓 핸들


소켓의 옵션

Protocol Level(프로토콜 레벨) : 옵션이름을 그룹짓기 위해 필요.

SOL_SOCKET : 일반적인 소켓의 옵션.

IPPROTO_IP : IP에 대한 소켓의 옵션.

IPPROTO_TCP : TCP에 대한 소켓의 옵션


※ SO_TYPE 옵션 : 소켓의 타입 정보(TCP(1)/UDP(2))값을 얻는다. 다시 재설정할 수 없다.

윈도우즈용 프로그램

sock_type.zip


9-2 SO_SNDBUF & SO_RCVBUF

getsockopt함수를 통해서 디폴트 버퍼의 크기를 구할 수 있다.

※ 리눅스 시스템 마다 입력 버퍼, 출력 버퍼의 크기는 다르다.

내 컴퓨터 우분투의 경우

입력버퍼 : 87380

출력버퍼 : 16384


setsockopt함수를 통해서 버퍼의 크기를 변경할 수 있다.

※ 바꿀 수 있는 최소 버퍼의 크기는 정해져 있다

※ 버퍼가 없으면 TCP를 할 수 없기 때문에 0으로 설정해도 최소값으로 바뀌어서 버퍼의 크기가 설정된다. 성능과 직결되는 문제이다.


9-3. SO_REUSEADDR

TIME_WAIT 상태?

연결 종료시 마지막 패킷 전송 실패를 대비하기 위한 상태


종료를 먼저 요청한 호스트가 나중에 소켓을 소멸시킨다. 

마지막 ACK 신호가 잘 전달되지 않았을 때를 대비해서 TIMEOUT이 존재한다.

이유 : 상대방(B)의 종료 요청(FIN)을 기다리는 데 걸리는 TIMEOUT이다.


서버의 연결 종료

서버에서 먼저 종료 요청 후, 다시 서버를 가동시키면?

서버가 종료 메세지를 보내고 TIMEOUT 시간동안은 서버 재가동 불가. 

이유 : 그 아이피와 포트가 사용중이기 때문.


TIME_WAIT 타이머의 재시작

TIME-WAIT 상태는 우리의 생각보다 더 길어 질 수 있다.


마지막 ACK신호를 못 보낼 경우 다시 FIN을 보낼 때 다시 TIMEOUT을 설정해야 되기 때문이다.


※ TIMEOUT이 걸린 소켓이라고 그 주소와 포트에 다시 소켓을 만들 수 있게 설정한다.

server_socket = socket(PF_INET, SOCK_STREAM, 0);

option = sizeof(option);

option = TRUE;

setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option));