티스토리 뷰

Network Programming

[TCP/IP]소켓의 다양한 옵션

군자동꽃미남 2016. 6. 26. 20:34

소켓에서 설정할 수 있는 다양한 옵션들

 Protocol Level

Option Name 

get 

set 

 SOL_SOCKET

SO_SNDBUF 

O

O

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
2
3
4
5
6
7
8
int getsockopt(
  _In_    SOCKET s,
  _In_    int    level,
  _In_    int    optname,
  _Out_   char   *optval,
  _Inout_ int    *optlen
);
 
cs
    • s : 설정 상태를 확인해 보고 싶은 소켓의 핸들.
    • level : 확인할 옵션의 프로토콜 레벨
    • optname : 확인할 옵션의 이름
    • optval : 확인 결과를 저장할 버퍼를 가리키는 포인터
    • optlen : optval 포인터가 가리키는 버퍼의 크기. 함수 호출이 완료되면, 전달된 포인터가 가리키는 변수에는 버퍼에 저장된 확인 결과의 길이가 바이트 단위로 저장된다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int tcp_sock;
int sock_type = -1;
socklen_t optlen;
int state;
 
 
optlen = sizeof(sock_type);
tcp_sock = socket(PF_INET, SOCK_STREAM, 0);
 
 
state = getsockopt(tcp_sock, SOL_SOCKET, SO_TYPE, &sock_type, &optlen);
if (state == -1)
    printf("error\n");
 
printf("소켓 타입 %d\n", sock_type);
cs



옵션을 변경하는 함수

1
2
3
4
5
6
7
8
int setsockopt(
  _In_       SOCKET s,
  _In_       int    level,
  _In_       int    optname,
  _In_ const char   *optval,
  _In_       int    optlen
);
 
cs
    • s : 설정 상태를 변경하고자 하는 소켓의 핸들.
    • level : 변경할 옵션의 프로토콜 레벨.
    • optname : 변경할 옵션의 이름.
    • optval : 변경할 옵션의 값을 저장한 버퍼의 포인터.
    • optlen : 전달하는 옵션의 바이트 단위 길이
1
2
3
4
5
6
7
8
9
10
11
12
13
int sock;
int snd_buf = 500;
int rcv_buf = 1000;
int state;
 
 
state = setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &rcv_buf, sizeof(rcv_buf));
if (state == -1)
    printf("error\n");
 
state = setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &snd_buf, sizeof(snd_buf));
if (state == -1)
    printf("error\n");
cs

getsockopt()로 결과를 확인하면 예상과 다른 결과를 보여주게 된다. 이유는, 입출력 버퍼의 문제는 상다잏 주의 깊게 다뤄져야 하기 때문에 요구하는 크기로 정확히 맞춰주지 않는다. 다만 setsockopt() 함수 호출을 통해서 버퍼 크기를 설정할 경우 인자로 전달되는 값을 참조하여(의견을 반영하여) 버퍼의 크기를 설정할 뿐이다.


Binding Error / TIME-WAIT 상태 해결

: 서버를 종료시키고 클라이언트를 종료시키면 서버 영역에서 클라이언트와 연결 상태에 있던 소켓이 바로 소멸되지 않고, 클라이언트 영역으로 FIN 메시지를 전송하게 된다. 이를 시작으로 four-way handshaking 과정을 거치게 된다. 그 다음 다시 한번 서버를 실행시켜 보면 Binding Error가 일어날 수 있는데, 이는 서버가 종료되면서 소켓이 바로 소멸되는 것이 아니라, TIME-WAIT 상태로 들어가기 때문인데, 이는 서버가 여전히 존재하고 있다는 뜻이 된다. 따라서 이러한 상태에서 bind 함수를 호출할 때 오류가 발생하는 것은 당연하다. IP와 Port가 사용되고 있기 때문이다.


-해결 방법-

1
2
3
int option = true;
socklen_t optlen = sizeof(option);
setsockopt(serv_sock, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option));
cs

소켓의 옵션 중에서 SO_REUSEADDR의 상태를 변경해 주면 된다. 



Nagle 알고리즘

TCP/IP 소켓 프로그래밍 218p 참고

'Network Programming' 카테고리의 다른 글

DNS 기본 동작 설명  (0) 2019.10.29
소켓의 우아한 연결 종료  (0) 2017.10.09
[TCP/IP]DNS  (0) 2016.06.26
[TCP/IP]스트림 half-close  (0) 2016.06.26
[TCP/IP]UDP  (0) 2016.06.26
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함