※ Rookiss님의 [C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버 강의를 보고 정리한 글입니다.
소켓엔 RecvBuffer,SendBuffer크기같은 여러가지 옵션들이 있다. 여러 가지가 있지만 자주 쓰일 수 있는 것만 간단히 알아보자.
::setsocketopt();
::getsocketopt();
set으로 옵션을 설정할 수 있고 get으로 옵션을 가져올 수 있다.
파라미터엔 소켓과, 레벨, 옵션이름, 옵션밸류, 옵션의 길이를 받아주고 있다.
level은 설정한 옵션을 해석하고 처리할 주체를 말한다.
많은 옵션들이 있지만 쓰일 만한 것들만 알아볼 것이다.
⇒ 주기적으로 연결 상태 확인 여부(TCP에서만)
옵션 타입: BOOL
만약 상대방이 소리소문없이 연결을 끊어버린다면, 상대방은 오랫동안 데이터를 안보내는 것인지 연결을 끊은 것인지 알 수 없다.
그래서 이 옵션을 통해 주기적으로 상태를 확인해 끊어진 연결을 감지할 수 있는 것이다.
bool enable = true;
::setsockopt(serverSocket, SOL_SOCKET, SO_KEEPALIVE,(char*)&enable, sizeof(enable));
⇒ 연결이 끊어질 때 송신 버퍼에 있는 데이터를 보낼것인가?
옵션 타입: 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: 대기시간
⇒ 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으로 한 번 알아 볼 수 있다.
⇒ IP주소 및 Port 재사용 여부
옵션 타입: BOOL
서버의 ip주소를 사용하려고하는데 다른 프로그램에서 이미 그 ip주소를 사용중이거나, 혹은 이전에 종료시켰던 프로그램에서 찌꺼기가 남았을 수도있다.
그때 강제적으로 재사용하겠다고 하는 것.
{
bool enable = true;
::setsockopt(serverSocket, SOL_SOCKET, SO_REUSEADDR, (char*)&enable, sizeof(enable));
}
⇒ Nagle 네이글 알고리즘 작동 여부
옵션 타입: BOOL
Nagle 알고리즘?? → 데이터가 충분히 크면 보내고, 그렇지 않으면 데이터가 충분히 쌓일 떄 까지 대기!
장점: 작은 패킷의 불필요하게 많이 생성되는 일 방지
단점: 반응 시간 손해
웬만해서 게임서버에선 사용하지않는 알고리즘이다.
TRUE → 사용 안함
{
bool enable = true;
::setsockopt(serverSocket, IPPROTO_TCP, TCP_NODELAY, (char*)&enable, sizeof(enable));
}
closeSocket을 통해 갑자기 닫아버리는 것은 좋지않다.
무전기로 대화를 할 때에도 오버라는 키워드를 통해 말을 모두 한 것을 알려준다.
그래서 Half_Close를 해주어야한다.
shutdown
::shutdown(serverSocket, SD_SEND);
실행하면 보낼 순 없지만 상대방 것은 받을 수 있다. 상대방에게 이제 난 보낼 의지가 없다는 것을 알려줌.
하지만 mmorpg 서버에선 파일 전송 처럼 모든 것을 받아야하는 경우가 아니라 해줄 필요는 없지만 매끄럽게 진행ㅇ하기 위해선 하는게 좋다고 알아주는 것이 좋다.