Department of Computer Engineering Socket Options Department of Computer Engineering Kyung Hee University. Choong Seon Hong
소켓의 옵션 조작 소켓의 옵션 조작 : 소켓의 기본적인 특성을 변경하는 것. 소켓의 기본적인 특성 입력 및 출력 버퍼의 크기 데이터 전송 방식(TCP or UDP) TTL(Time to live) 소켓의 옵션은 거의 대부분 변경이 가능하지만 참조만 가능한 것도 있다.
소켓 옵션 Protocol Level Option Name get set SOL_SOCKET IPPROTO_IP SO_SNDBUF SO_RCVBUF SO_REUSEADDR SO_KEEPALIVE SO_BROADCAST SO_DONTROUTE SO_OOBINLINE SO_ERROR SO_TYPE IPPROTO_IP IP_TOS IP_TTL IP_MULTICAST_TTL IP_MULTICAST_LOOP IP_MULTICAST_IF IPPROTO_TCP TCP_KEEPALIVE TCP_NODELAY TCP_MAXSEG
소켓 옵션 변경 함수 1 #include <sys/types.h> 소켓에 현재 지정되어 있는 옵션 값을 알아내는 함수 sock : 설정상태를 확인해 보고 싶은 소켓의 파일 디스크립터를 인자로 전달 level : 확인할 옵션의 프로토콜 레벨을 인자로 전달 optname : 확인할 옵션의 이름을 전달 optval : 확인 결과를 저장할 버퍼를 가리키는 포인터를 전달 optlen : optval 포인터가 가리키는 버퍼의 크기를 전달한다. 함수 호출이 완료되면 전달된 포인터가 가리키는 변수에는 버퍼에 저장된 확인 결과의 길이가 바이트 단위로 저장 성공 시 0, 실패시 -1 리턴 #include <sys/types.h> #include <sys/socket.h> int getsockopt(int sock, int level, int optname, void *optval, int *optlen);
소켓 옵션 변경 함수 2 #include <sys/types.h> 소켓에 현재 지정되어 있는 옵션 값을 변경하는 함수 sock : 설정상태를 변경하고자 하는 소켓의 파일 디스크립터를 인자로 전달 level : 변경할 옵션의 프로토콜 레벨을 인자로 전달 optname : 변경할 옵션의 이름을 전달 optval : 변경할 옵션의 값을 저장한 버퍼를 가리키는 포인터를 전달 optlen : 전달하는 옵션의 바이트 단위 길이를 전달 성공 시 0, 실패시 -1 리턴 #include <sys/types.h> #include <sys/socket.h> int setsockopt(int sock, int level, int optname, const void *optval, int optlen);
소켓옵션의 종류 SOL_SOCKET : 소켓 레벨의 옵션을 변경 IPPROTO_IP : IP 레벨의 옵션을 변경 IPPROTO_TCP : TCP 레벨의 옵션을 변경
SOL_SOCKET 레벨의 옵션 SO_BROADCAST : 방송형 메시지 전송 허용 SO_DEBUG : DEBUG 모드를 선택 SO_REUSEADDR : 주소 재사용 선택 SO_LINGER : 소켓을 닫을 때 미전송된 데이터가 있어도 지정된 시간만큼 기다렸다가 소켓을 닫음 SO_KEEPALIVE : TCP의 keep_alive 동작 선택 SO_OOBINLINE : OOB 데이터를 일반 데이터처럼 읽음 SO_RCVBUF : 수신버퍼의 크기 변경 SO_SNDBUF : 송신버퍼의 크기 변경
IPPROTO_IP 레벨의 옵션 IP_TTL : Time To Live 변경 IP_MULTICAST_TTL : 멀티캐스트 데이터그램의 TTL 변경 IP_ADD_MEMBERSHIP : 멀티캐스트 그룹에 가입 IP_DROP_MEMBERSHIP : 멀티캐스트 그룹에서 탈퇴 IP_MULTICAST_LOOP : 멀티캐스트 데이터그램의 loopback 허용 여부 IP_MULTICAST_IF : 멀티캐스트 데이터그램 전송용 인터페이스 지정
IPPROTO_TCP 레벨의 옵션 TCP_KEEPALIVE : keep-alive 확인 메시지 전송 시간 지정 TCP_MAXSEG : TCP의 최대 메시지 크기 지정 TCP_NODELAY : Nagle 알고리즘의 선택
예제 확인 sock_type.c
소켓 옵션의 종류 – SO_RCVBUF, SO_SNDBUF TCP,UDP는 송신버퍼와 수신버퍼를 가짐 TCP의 경우 write() 호출시 데이터를 송신 버퍼로 복사 데이터가 송신버퍼에 모두 복사되면 시스템이 데이터를 전송 전송 데이터는 유지하고 있다가 ACK를 수신 후 삭제 송신버퍼가 가득차면 write()는 블록됨 송신/수신버퍼의 크기를 사용자가 지정할 수 있음 SO_SNDBUF 송신 버퍼의 크기 확인 및 지정 SO_RCVBUF 수신 버퍼의 크기 확인 및 지정 송신/수신 버퍼의 크기 지정 방법 3-way handshake 후에는 버퍼 크기 변경이불가 서버의 경우 listen() 호출 이전에 설정 클라이언트의 경우 connect() 호출 이전에 설정
예제 확인 get_buf.c set_buf.c
소켓 옵션의 종류 – SO_REUSEADDR 동일한 소켓주소를 여러 프로세스 또는 한 프로세스 내의 여러 소켓에서 중복 사용을 허용 소켓주소 재사용 옵션이 필요한 경우 TIME-WAIT 상태에서의 주소 재사용 ACTIVE CLOSE 상태의 호스트는 TIME-WAIT 상태를 가지며 포트번호를 중복하여 사용할 수 없음 자식 프로세스가 서버인 경우 부모 프로세스가 종료된 후 다시 시작하면 포트번호 사용중 에러가 발생 소켓 주소 재사용 옵션은 bind() 호출 이전에 설정해야 함 멀티홈 서버의 경우 호스트가 두개 이상의 IP주소를 가지며 같은 포트번호를 사용해야 하는 경우가 있음 완전 중복 바인딩 동일한 IP 주소와 포트번호를 중복하여 bind()하는것, UDP에서만 가능
TCP 연결종료
예제 확인 reuseaddr.c 1 5 7– CTRL + C 8 2 3 4 – CTRL + C 6
소켓 옵션의 종류 – SO_KEEPALIVE TCP 연결이 정상적으로 지속되고 있는지를 주기적으로 확인하는 기능 이 옵션이 셋트되어 있으면 TCP는 확인시간 동안 데이터 수신이 없을 때 TCP 연결이 살아 있는지 물어보는 메세지를 전송(keep alive prove) Keep Alive Prove의 세 가지 응답 상대방이 ACK를 보낸다. TCP 연결이 정상적으로 동작 상대방이 RST 에러를 보낸다. 상대방 호스트가 꺼진 후 재부팅 된 상태 TCP는 소켓을 닫음 아무 응답이 없다. 질문을 몇 번 더 보내본 후 연결 종료 중간라우터의 응답 ICMP(host unreachable error, network unreachable error)
소켓 옵션의 종류 – SO_KEEPALIVE 사용법 #include <sys/types.h> #include <sys/socket.h> int set = 1; int setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (char *) &set, sizeof(set));
소켓 옵션의 종류 – SO_LINGER SO_LINGER close() 호출시 송신버퍼에 데이터가 남아 있어도 close()는 즉시 리턴 되고 TCP는 이 데이터를 모두 전송한 후 실제 연결을 종료 close() 함수가 리턴한 시점에서 모든 데이터가 전송된 것을 보장하지는 않음 SO_LINGER 옵션은 close()를 호출한 후 상대방에서 정상적으로 종료절차가 이루어졌는지를 확인하기 위해 사용 close()는 지정한 linger 시간 동안 또는 정상 종료 시까지 블록됨 정상 종료 전에 linger 시간이 타임아웃되면 ETIMEDOUT 에러 발생
소켓 옵션의 종류 – SO_LINGER 사용법 #include <sys/types.h> #include <sys/socket.h> struct linger{ int l_onoff; int l_linger; } struct linger ling; ling.l_onoff = 1; ling.l_linger = 0; If(setsockopt(sockd, SOL_SOCKET, SO_LINGER, (void *) &ling, sizeof(struct linger)) !=0){ perror(“setsockopt fail”); exit(1);
소켓 옵션의 종류 – SO_LINGER 4-way handshake FIN, ACK, FIN, ACK의 순서로 동작 호스트 A가 B로 데이터 전송 후 close()를 호출한 시점에서 B가 모든 데이터를 읽었다고 확신할 수 없음 Shutdown() – LINGER 옵션을 사용하지 않을경우 상대방이 FIN을 보낼때 까지 기다리도록 함 int shutdown(int s, int how); How SHUT_WR : 송신 스트림만 닫음 SHUT_RD : 수신 스트림만 닫음 SHUT_RDWR : 송수신 스트림을 모두 닫음 상대방이 FIN을 보낼때까지 기다리는 코드 1. write(sock, buf, size); 2. shutdown(sock, SHUT_WR); 3. while(read(sock, buf, size) > 0); 4. shutdown(sock, SHUT_RD);
기타 옵션 SO_RCVLOWAT, SO_SNDLOWAT SO_DONTROUTE TCP_MAXSEG 송수신버퍼의 최소량 설정 옵션 SO_DONTROUTE 데이터그램 송신시에 시스템이 배정하는 라우팅 경로를 사용하지 않도록 함. TCP_MAXSEG TCP의 최대 세그먼트 크기값(MSS)을 읽거나 변경 MSS 변경은 모든 시스템이 지원하지 않음(LINUX 지원) MSS는 연결 설정 전에 해야 함 너무 큰 값을 선택하면 연결 설정 과정에서 원하는 값보다 작게 지정될수도 있음
멀티캐스트 프로그래밍 멀티캐스트 하나의 데이터그램을 다수의 호스트로 동시에 전송 멀티캐스트 그룹 하나의 데이터그램은 네트워크 내에서 복제되어 다수의 호스트로 전송 LAN 뿐만 아니라 인터넷에 연결되어 있는 모든 호스트에 가능 호스트는 해당 멀티캐스트 그룹에 가입되어 있어야 함 멀티캐스트 그룹 멀티캐스트 데이터그램을 수신하고자 하는 호스트들의 집합 클래스 D의 IP주소를 그룹 주소로 사용 224.0.0.0 부터 239.255.255.255 사이의 값을 가짐 해당 그룹 주소를 목적지로 하여 UDP 데이터그램을 전송 중간 라우터가 Multicast Routing Protocol을 지원해야함
소켓 옵션 지정 멀티캐스트와 관련된 소켓 옵션 멀티캐스트 그룹 가입/탈퇴 IP_ADD_MEMBERSHIP : 그룹에 가입 IP_DROP_MEMBERSHIP : 그룹에서 탈퇴 IP_MULTICAST_LOOP : 멀티캐스트 패킷의 loopback 허용 여부 IP_MULTICAST_TTL : 패킷의 TTL 값 지정 IP_MULTICAST_IF : 패킷 전송을 위한 인터페이스 지정 멀티캐스트 그룹 가입/탈퇴 ip_mreq 구조체 사용 struct ip_mreq{ struct in_addr imr_multiaddr; struct in_addr imr_interface; // 자신의 인터페이스(IP 주소) }
멀티캐스트 데이터그램 송신 멀티캐스트 그룹에 가입하지 않아도 됨 해당 멀티캐스트 주소로 패킷을 전송하기 멀티캐스트 송신 호스트가 멀티캐스트 그룹원일 경우 패킷은 기본적으로 자신에게 loopback 된다.
멀티캐스트 데이터그램 수신 수신을 위해서는 그룹에 가입해야 함
프로그램 예제 news_sender.c news_receiver.c
Graceful Exit of Socket Connection Department of Computer Engineering Kyung Hee University. Choong Seon Hong
입력 및 출력 스트림 Host Host 입력 스트림 : 데이터 수신을 위한 스트림 출력 스트림 : 데이터 전송을 위한 스트림
소켓 연결 종료의 문제점 Stream close 함수의 호출 : 입력 출력 스트림 완전 종료 일방적인 방식의 완전종료는 경우에 따라서 문제가 될 수 있다. Stream MSG Host B Host A MSG 소멸!
Half-close Stream Half-close : 입력 및 출력 스트림 중 하나의 스트림만 종료 무사히 전송 MSG Host B Host A MSG 무사히 전송
Half-close 기능의 함수 #include <sys/socket.h> int shutdown(int s, int how); 상수값 모드 정의 SHUT_RD 입력 스트림 종료 1 SHUT_WR 출력 스트림 종료 2 SHUT_RDWR 입,출력 스트림 종료
출력 스트림 종료의 필요성 출력 스트림을 종료하게 되면, 연결되어 있던 호스트로 EOF 메시지 전달 EOF 전송 시, 상대 호스트의 데이터 수신 함수(read, recv)는 0을 리턴 Server Client 연결요청 파일전송 EOF전송 Thank you
파일 전송 서버 / 클라이언트 프로그 램 예제 file_server.c, file_client.c 실행하기