본문 바로가기

Network/중급 TCP/IP socket

01. 소켓옵션(sockopt) / getsockot setsockopt

소켓옵션 소켓동작 자체에 관련된 여러가지 옵션의 값을 조정할수 있고 바꿀수 있습니다

소켓옵션을 이용하여 특히 소켓 설정 정보를 읽어오는 getsockopt를 이용하여 TCP / UDP타입을 확인하여 봅시다

 

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>

void error_handling(char * message);

int main()
{
  int tcp_sock, udp_sock;
  int sock_type = -1;
  socklen_t optlen;
  int state;
  
  optlen = sizeof(sock_type);
  tcp_sock = socket(PF_INET, SOCK_STREAM, 0);
  udp_sock = socket(PF_INET, SOCK_DGRAM, 0);

  printf("SOCK_STREAM : %d \n", SOCK_STREAM);
  printf("SOCK_DGRAM : %d \n", SOCK_DGRAM);
  
  state = getsockopt(tcp_sock, SOL_SOCKET, SO_TYPE, &sock_type, &optlen);
  if(state)
    error_handling("getsockopt() error");
  printf("첫번째 소켓의 타입은 %d\n", sock_type);
  
  
  state = getsockopt(udp_sock, SOL_SOCKET, SO_TYPE, &sock_type, &optlen);
  if(state)
    error_handling("getsockopt() error");
  printf("두번째 소켓의 타입은 %d\n", sock_type);
  return 0;
  
}
void error_handling(char * message)
{
  fputs(message, stderr);
  fputc('\n', stderr);
  exit(1);  
}


결과>>


소켓의 다양한 옵션

 

getsockopt / setsockopt

 

1. getsockopt 소켓 설정 정보(옵션의값) 읽어오는 함수

함수는 특정한 형태(type), 특정한 상태(state)로 연관 되어있는 소켓옵션에 대해 설정되어 있는 값을 optval 매개변수에 저장해서 얻어내는 함수입니다.

 

#include <sys/types.h>

#include <sys/socket.h>

 

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

성공시 0, 실패 시  -1 리턴

 

예제소스

getsockopt(sock, SOL_SOCKET, SO_SNDBUF, &snd_buf, &len);

 

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>

void error_handling(char *message);

int main()
{
  int sock;
  int snd_buf, rcv_buf;
  int state;
  socklen_t  len;

  sock = socket(PF_INET, SOCK_STREAM,0);
  
  len = sizeof(snd_buf);
  state = getsockopt(sock, SOL_SOCKET, SO_SNDBUF, &snd_buf, &len);
  if(state)
    error_handling("getsockopt() error ");

  len = sizeof(rcv_buf);
  state = getsockopt(sock, SOL_SOCKET, SO_RCVBUF, &rcv_buf, &len);
  if(state)
    error_handling("getsockopt() error ");

  printf("데이터 입력받기 위한 소켓의 버퍼 크기 : %d(수신버퍼) \n", rcv_buf);
  printf("데이터 출력받기 위한 소켓의 버퍼 크기 : %d(송신버퍼) \n", snd_buf);

  return 0;
}

void error_handling(char * message)
{
  fputs(message,stderr);
  fputc('\n', stderr);
  exit(1);
}


결과>>


2. setsockopt 소켓 옵션을 변경(설정)하는 함수

함수는 지정된 소켓의 옵션을 특정한 형태(type), 상태(state)로 결합하기 위해서 지정한 소켓옵션 값을 셋팅하는 함수입니다.

 

#include <sys/types.h>

#include <sys/socket.h>

 

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

성공시 0, 실패 시  -1 리턴 

 

예제소스

setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &rcv_buf,sizeof(rcv_buf));


#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>

void error_handling(char *message);

int main()
{
  int sock;
  int snd_buf = 500;
  int rcv_buf = 1000;

  int state;
  socklen_t  len;

  sock = socket(PF_INET, SOCK_STREAM,0);
  /*입출력 버퍼 크기 설정*/
  state = setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &rcv_buf,sizeof(rcv_buf));
  if(state)
    error_handling("setsockopt() error ");

  state = setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &snd_buf,sizeof(snd_buf));
  if(state)
    error_handling("setsockopt() error ");

  /*입출력 버퍼 크기 확인*/  
  len = sizeof(rcv_buf);
  state = getsockopt(sock, SOL_SOCKET, SO_SNDBUF, &rcv_buf, &len);
  if(state)
    error_handling("getsockopt() error ");

  len = sizeof(snd_buf);
  state = getsockopt(sock, SOL_SOCKET, SO_RCVBUF, &snd_buf, &len);
  if(state)
    error_handling("getsockopt() error ");

  printf("데이터 입력받기 위한 소켓의 버퍼 크기 : %d(수신버퍼) \n", rcv_buf);
  printf("데이터 출력받기 위한 소켓의 버퍼 크기 : %d(송신버퍼) \n", snd_buf);

  return 0;
}

void error_handling(char * message)
{
  fputs(message,stderr);
  fputc('\n', stderr);
  exit(1);
}


결과>>


참고
snd와 rcv에 각각 500 1000의 값을 넣었지만 적용되지 않았습니다
이 경우에는 사용자가 시스템에게 '이값을 원한다'라고 알려주는 힌트정도로 생각하면 됩니다
리소르의 관리는 시스템의 몫이며 버퍼 크기 조정시 다른부분도 고려를 하기 때문에 이러한 결과가 나오게 됩니다

getsockopt / setsockopt의 인자  설명 

int socket
   [입력] 작업 대상 소켓의 기술자(descriptor)를 명시합니다.

int level
   [
입력] 소켓 옵션 레벨이 정의 되며, SOL_SOCKET IPPROTO_TCP 중 하나가 될 수 있습니다.

int optname
   [
입력]이 함수에 의해서 반환될(검색될) 값에대한 소켓 옵션을 명시합니다.

voif *optval
   [
출력] 요청된 옵션에 대한 반환되는 옵션값이 저장될 버퍼에 대한 포인터 입니다.

sockeln_t *optlen
   [
/출력] optval 버퍼의 크기를 나타내는 정수로 포인트 합니다.


 

 int optname 종류 및 설명

옵션값(Value)

데이터형태(Type)

의미(Meaning)

SO_ACCEPTCONN

BOOL

TRUE 일 경우 소켓이 리슨 하고 있습니다.

SO_BROADCAST
 

BOOL
 

TRUE 일 경우 소켓은 브로드캐스트(broadcast) 메시지를

전송하기 위해 만들어졌습니다.

SO_DEBUG

BOOL

TRUE 일 경우 디버깅이 가능합니다.

SO_DONTLINGER

BOOL

TRUE 일 경우 SO_LINGER 옵션은 무시됩니다.

SO_DONTROUTE

BOOL

TRUE 일 경우 라우팅이 무시됩니다.

SO_ERROR

int

에러상태를 반환하고, 클리어 됩니다.

SO_GROUP_ID

GROUP

소켓이 속해있는 그룹 식별자를 의미합니다.

SO_GROUP_PRIORITY
 

int
 

소켓에 관련된 우선사항은 소켓 그룹의 부분 입니다.

SO_KEEPALIVE

BOOL

TRUE 일 경우 keepalive가 전송되고 있습니다.

SO_LINGER

struct LINGER

현재의 linger 옵션을 반환 합니다.

SO_MAX_MSG_SIZE
 
 

unsigned int
 
 

SOCK_DGRAM 과 같은 소켓 형태에서 메시지의 최대 크기입니다. 스트림 소켓에서는 아무런 의미가 없습니다.

SO_OOBINLINE
 

BOOL
 

TRUE 일 경우 아웃오브밴드 데이터가 정상적인 데이터 스트림으로 수신되고 있습니다.

SO_PROTOCOL_INFO
 

WSAPROTOCOL_INFO
 

소켓에 대해 바인드된 프로토콜 정보를 나타냅니다.

SO_RCVBUF

int

수신 버퍼크기를 의미합니다.

SO_REUSEADDR
 

BOOL
 

TRUE일 경우 소켓은 이미 사용중인 어드레스로 묶였습니다.

SO_SNDBUF

int

전송 버퍼의 크기

SO_TYPE
 

int
 

소켓의 타입 (:SOCK_STREAM, SOCK_DGRAM)