C++ 소켓 옵션

정은성·2023년 5월 29일
2
post-thumbnail

※ Rookiss님의 [C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버 강의를 보고 정리한 글입니다.

소켓엔 RecvBuffer,SendBuffer크기같은 여러가지 옵션들이 있다. 여러 가지가 있지만 자주 쓰일 수 있는 것만 간단히 알아보자.

방법

::setsocketopt();
::getsocketopt();

set으로 옵션을 설정할 수 있고 get으로 옵션을 가져올 수 있다.

파라미터엔 소켓과, 레벨, 옵션이름, 옵션밸류, 옵션의 길이를 받아주고 있다.

Level

level은 설정한 옵션을 해석하고 처리할 주체를 말한다.

  1. SOL_SOCKET → 소켓 코드에서 처리
  2. IPPROTO_IP → IPv4 에서 처리
  3. IPPROTO_TCP → TCP 프로토콜에서 처리

Option

많은 옵션들이 있지만 쓰일 만한 것들만 알아볼 것이다.

SO_KEEPABLE

⇒ 주기적으로 연결 상태 확인 여부(TCP에서만)

옵션 타입: BOOL

만약 상대방이 소리소문없이 연결을 끊어버린다면, 상대방은 오랫동안 데이터를 안보내는 것인지 연결을 끊은 것인지 알 수 없다.

그래서 이 옵션을 통해 주기적으로 상태를 확인해 끊어진 연결을 감지할 수 있는 것이다.

bool enable = true;																			
::setsockopt(serverSocket, SOL_SOCKET, SO_KEEPALIVE,(char*)&enable, sizeof(enable));

SO_LINGER

⇒ 연결이 끊어질 때 송신 버퍼에 있는 데이터를 보낼것인가?

옵션 타입: LINGER

만약 Send를 하고 곧바로 CloseSocket을 해버린다면 SendBuffer에 올라간 데이터들은 어떻게 처리할 것인지에 대한 옵션이다.

LINGER linger;
linger.l_onoff = 1;
linger.l_linger = 5;
::setsockopt(serverSocket, SOL_SOCKET, SO_LINGER, (char*)&linger, sizeof(linger));

l_onoff: 0이면 바로 closeSocket, 아니면 linger초만큼 대(default 0)

l_ilnger: 대기시간

SO_SNDBUF, SO_RECVBUF

⇒ SendBuffer크기, RecvBuffer 크기

옵션 타입: int

소켓의 버퍼 크기를 조절하는 옵션이다.

int32 sendBufferSize;
int32 optionLen = sizeof(sendBufferSize);
::getsockopt(serverSocket,SOL_SOCKET, SO_SNDBUF, (char*)&sendBufferSize, &optionLen);
cout << "송신 버퍼 크기: " << sendBufferSize << endl;

int32 recvBufferSize;
optionLen = sizeof(recvBufferSize);
::getsockopt(serverSocket,SOL_SOCKET, SO_SNDBUF, (char*)&recvBufferSize, &optionLen);
cout << "수신 버퍼 크기: " << recvBufferSize << endl;

하지만 조절할 때 터무니 없는 값을 넣으면 적용이 안될 수도 있다.

그러니 바뀌었는지 알고싶다면, set후 get으로 한 번 알아 볼 수 있다.

SO_REUSEADDR

⇒ IP주소 및 Port 재사용 여부

옵션 타입: BOOL

서버의 ip주소를 사용하려고하는데 다른 프로그램에서 이미 그 ip주소를 사용중이거나, 혹은 이전에 종료시켰던 프로그램에서 찌꺼기가 남았을 수도있다.

그때 강제적으로 재사용하겠다고 하는 것.

{
	bool enable = true;
	::setsockopt(serverSocket, SOL_SOCKET, SO_REUSEADDR, (char*)&enable, sizeof(enable));
}

TCP_NODELAY

⇒ Nagle 네이글 알고리즘 작동 여부

옵션 타입: BOOL

Nagle 알고리즘?? → 데이터가 충분히 크면 보내고, 그렇지 않으면 데이터가 충분히 쌓일 떄 까지 대기!

장점: 작은 패킷의 불필요하게 많이 생성되는 일 방지

단점: 반응 시간 손해

웬만해서 게임서버에선 사용하지않는 알고리즘이다.

TRUE → 사용 안함

{
	bool enable = true;
	::setsockopt(serverSocket, IPPROTO_TCP, TCP_NODELAY, (char*)&enable, sizeof(enable));
}

그외

closeSocket을 통해 갑자기 닫아버리는 것은 좋지않다.

무전기로 대화를 할 때에도 오버라는 키워드를 통해 말을 모두 한 것을 알려준다.

그래서 Half_Close를 해주어야한다.

shutdown

  1. SD_SEND: send를 막는다.
  2. SD_RECEIVE: recv를 막는다.
  3. SD_BOTH: 둘다 막는다.
::shutdown(serverSocket, SD_SEND);

실행하면 보낼 순 없지만 상대방 것은 받을 수 있다. 상대방에게 이제 난 보낼 의지가 없다는 것을 알려줌.

하지만 mmorpg 서버에선 파일 전송 처럼 모든 것을 받아야하는 경우가 아니라 해줄 필요는 없지만 매끄럽게 진행ㅇ하기 위해선 하는게 좋다고 알아주는 것이 좋다.

0개의 댓글