tcp기반의 입/출력 버퍼에 대해서..


이런 경우를 생각해 보자.
tcp 기반에서의 전송은 경계가 없어서, 전송 횟수가 한번이라 치더라도 수신측에서 두번을 읽을 수 있고,
반대로 전송 횟수가 두번일지라도 수신측에서 한번에 두번의 전송을 읽을 수 있다고도 했다.
예를들어 서버가 데이터를 한패킷에 40바이트를 송신하고, 클라이언트에서 10바이트씩 네번 수신하는경우를 생각해 보자.
이 경우에 한번에 40바이트를 전송했으므로 분명히 클라이언트측으로 40바이트가 한꺼번에 날라갔을 텐데,
클라이언트는 여유있게 4번에 걸쳐서 10바이트씩 총40바이트를 수신한다?? 그러면 도대체 30바이트는 어디서 대기하고 있는걸까?
이렇게 생각해 볼 수 있지 않은가. 서버에서 한꺼번에 송신한 40바이트를 클라이언트 측에서 마련된 버퍼에 수신되어 있다가
데이터를 프로그램에서 조금씩 읽어들였다고 말이다.
그림으로 표현하자면 이런 상황?

소켓생성시 커널은 서버컨 클라이언트건 입/출력을 위한 버퍼를 각각 생성해준다. 그리고 데이터의 송/수신시 버퍼가 사용된다.
이런 상황은 어떻게 설명해야 할까??
클라이언트의 입력버퍼의 크기가 40바이트였는데 서버에서 80바이트를 전송했다. 그러면 40바이트는 버퍼 밖에서 기다려야 하는가?
사실 이러한 일은 일어나지 않는다. tcp 기반 데이터 송/수신에는 수신할 수 있는 버퍼의 용량은 넘어서서 데이터를 전송하지 않는다.
서버와 클라이언트는 데이터의 흐름을 제어해 가며 데이터를 주고받기 때문에,서버에서는 클라이언트가 수용할 수 있을 만큼의
데이터만을 전송하게 된다. 흐름제어를 위한 기법으로 슬라이딩윈도우(sliding window) 프로토콜을 사용한다고 한다.
/////////////////////////////////////////////
슬라이딩 윈도우 프로토콜 부가설명
서버영역에서 write()함수호출을 통해 100바이트를 송신했다 치자. write()함수호출과 동시에 모든데이터가 전송되는게 아니다.
호출과 동시에 서버의 출력버퍼로 100바이트가 전달되고 그리고 나서 tcp에 의해서 수신측 호스트가 수용할 수 있는 만큼의 데이터만 패킷화해서 전송하기 시작한다.
예를 들어, 데이터를 수신하는 호스트가 현재 30바이트까지 수용할 수 있다는 메시지를 서버로 전송하면,
100바이트 중에서 30바이트만 패킷화해서 전송하고 70바이트는 버퍼에 남겨둔다. 후에 클라이언트가 다시 20바이트까지 수신할 수 있다고 메시지를 전달해오면 20바이트를 패킷화 하여 다시 송신한다. 이러한 식으로 총 100바이트를 전송하므로 패킷이 몇 번 생성되는지는 알 수가 없다.
/////////////////////////////////////////////
결론은 클라이언트와 서버 모두 소켓 생성시 입/출력을 위한 버퍼가 커널에 의해 생성되며, 데이터 송/수신이 흐름제어(flow control)
프로토콜을 기반으로 해서 진행이 된다는 것.
아래 그림으로 알아볼 수 있다.

흐름 제어(flow control)도 tcp가 하는 중요한 일 중 하나이다. (udp에 비해 많이 복잡함)




최근 덧글