눈팅하는 게임개발자 블로그
블로킹 소켓(송신, 수신) 버퍼 본문
www.gilbut.co.kr/book/view?bookcode=BN002400
해당 책의 내용 중 일부를 정리.
소켓 버퍼는 송신 버퍼와 수신 버퍼를 하나씩 가지고 있다.
먼저 송신 버퍼는 일련의 바이트 배열과도 같다.
크기는 고정되어 있으나 마음대로 크기를 변경할 수도 있다.
송신 버퍼(Send Buffer)
송신 버퍼는 큐와 마찬가지로 FIFO(First in First Out, 선입선출)형태로 작동하는데,
send함수에 data를 인자로 실행하면 data는 일단 송신 버퍼에 채워진다.
이후 송신 버퍼에 채워진 data는 잠시 후 통신 선로를 통해 점차적으로 빠져나간다.
따라서 송신 버퍼는 뭔가가 채워지더라도 곧 빈 상태가 된다.
Send함수를 실행하는 과정
크기가 5바이트인 송신 버퍼가 있다.
send(A)에서 푸시.이제 send 함수를 실행한다. 그러면 소켓 송신 버퍼의 가장 앞에 A가 채워진다.
잠시 후 운영체제로 A가 네트워크 선로를 통해 송출된다. 이에 따라 송신 버퍼는 다시 빈 상태가 된다.
송신 버퍼에서 A를 팝.
잠시 후 BCDEF 데이터를 보내는 send함수가 실행된다.
send(BCDEF)에서 푸시.
B C D E F |
운영체제는 송신 버퍼가 비어 있지 않음을 확인하고 맨 앞에 있는 데이터를 팝하여 송신한다.
C D E F |
B가 팝된다.
여기서 데이터 G, H를 보내는 send함수가 실행될 때
send(G), send(H)
C D E F |
G, H가 버퍼에 들어가기 위해서는 2바이트의 자리가 필요한데 자리는 1바이트밖에 없다.
여기서 send(H) 함수의 블로킹이 발생한다.
G는 버퍼에 들어가고, H는 들어갈 자리가 없어 블로킹이 발생하게 된다.
send(H)
C D E F G |
다음 C가 운영체제에 의해 팝되어 송신 버퍼에 자리가 생기기 전까지 블로킹은 지속되고.
D E F G H |
자리가 생기면 H가 송신 버퍼에 들어가고 send(H)는 블로킹이 해제되어 값을 반환하게 된다.
수신 버퍼(Receive Buffer)
수신 버퍼 안에 데이터가 수신되는 것이 있을 때마다 계속되서 채워진다.
수신 버퍼를 방치하게 되면 결국 꽉 차게 되고, 꽉 차게 되면 더 이상 데이터를 받지 않는다.
소켓에서 데이터를 수신하는 함수를 호출하여(recv)수신 버퍼에서 이미 수신이 완료된 데이터를 꺼낼 수 있다.
수신 버퍼가 완전히 비어있으면 데이터를 수신하는 함수(recv)는 블로킹이 일어난다.
송신 버퍼가 완전히 차면 데이터를 송신하는 함수가 블로킹이 일어난다는 점과 정반대의 현상이다.
수신 버퍼가 가득 차면?
TCP의 수신 함수인 recv는 1바이트라도 수신할 데이터가 수신 버퍼에 있다면 즉시 값을 반환한다.
이외에는 1바이트라도 데이터가 수신 버퍼에 채워질 때까지 블로킹한다.
반대로 수신 함수가 수신 버퍼에서 데이터를 꺼내는 속도보다
운영체제가 수신 버퍼에 데이터를 채워넣는 속도가 더 빠르다면 어떻게 될까.
TCP는 수신 버퍼에 남은 공간이 하나도 없을 때까지 완전히 채워지게 된다.
수신 버퍼가 꽉 차면, TCP로 데이터를 보내는 함수인 send함수가 블로킹 상태가 된다.
이 상태에서 수신 버퍼에서 데이터를 꺼내는 recv함수를 실행하지 않으면 TCP통신은 전혀 이루어지지 않고
TCP 연결만이 유지되어있는 상태가 된다.
정리하자면 TCP 송신 함수로 송신 버퍼에 데이터를 쌓는 속도보다 수신 함수로
수신 버퍼에서 데이터를 꺼내는 속도가 느리다고 해서 TCP 연결이 끊어지지는 않는다는 것이다.
단지 실제 송신 속도가 느린 쪽에 맞추어 속도를 자동으로 조절할 뿐이다.
이런 점이 TCP의 신뢰도가 높다는 점의 근거가 될 수 있다.
UDP의 경우는
UDP의 경우 recv함수가 실행되었을 때 수신 버퍼에 데이터그램이 최소 1개 도착해 있으면 즉시 반환한다.
그렇지 않으면 데이터그램이 1개 도착할 때까지 블로킹 되는데.
송신 함수가 수신 함수보다 데이터를 처리하는 속도가 빠르다면
수신 버퍼가 가득찬 상태에서는 데이터그램이 버려지기 때문에 데이터 유실이 발생하게 된다.
'공부한거 > 게임서버 프로그래밍' 카테고리의 다른 글
수직 확장, 수평 확장 (0) | 2020.11.03 |
---|---|
패킷 유실시 UDP / TCP에서 발생하는 일 (0) | 2020.10.22 |
게임 메시지(데이터) 형식 (0) | 2020.10.22 |