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))값을 얻는다. 다시 재설정할 수 없다.
윈도우즈용 프로그램
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));