PC와 서버가 TCP/IP 연결을 하고, File download하는 상황을 예시로 든다.
Server:
서버에선 서버 프로그램이 실행되고 Socket이 열려있어 클라이언트와 통신을 할 것 이다. 소켓은 기본적으로 파일이기에 프로세스가 동적으로 메모리 할당을 해준다. 기본적으로 프로세스가 파일에 할 수 있는 조작은 RWX가 있다. (소켓이니 X는 생략)
소켓이 읽으면 Receive며 쓴다는 Send다. 즉 프로세스가 소켓에 대해 I/O를 실행한다고 생각하면 좋다(Stream).
HDD에 파일이 들어가 있다고 생각해보자, 그럼 파일 시스템이 드라이버에 접근을 해서 HDD에 데이터를 읽고 쓰는 행위를 반복할 수 있다. HDD에서 데이터를 읽어올 땐 한번에 가져오는 것이 아닌 매우 작은 단위로 쪼개서 적재해온다.
TCP와 소켓이 맞닿는 지점에선 데이터의 분해가 일어난다. 그럼 쪼개온 데이터는 분해지점으로 넘어와 Copy되어 적재한다. 이런 과정을 Buffered I/O라고 한다. TCP에서 IP쪽으로 데이터(buffer)가 넘어가는데 이때 Segment 단위로 한번 더 쪼개준다. 그럼 하나의 Segment를 Packet처리해 한번 더 포장해준다. 그리고 포장된 Packet들을 Frame에 적재하여 데이터 전송을 해준다. 중요한건, Frame에 담긴 Packet은 한번에 엔드포인트에서 엔드포인트로 이동하지 않고, 여러번 Frame을 갈아타면서 전송이 된다.
Client:
도착지 엔드포인트 쪽에 도달하면 다시 클라이언트 단의 소켓을 통해 한번 더 File I/O Buffer를 하게 된다. Frame이 클라이언트 측에 도달하면 decapsulation이 일어나면서 사라지게 되고, TCP단에 바로 Segment로 분해가된다. Segment를 잘 수신되었다면, 다음 Segment 번호를 ACK 해준다.
서버측에서는 다음 Segment ACK를 Wait하기 때문에 속도지연 발생이 일어난다.
수신측의 TCP Buffer 사이즈를 윈도우 사이즈라고한다. 이때 window는 운영체제와 관련이 없는 별개의 용어다. ACK에는 window size가 적재되어있는데, 이 사이즈에 따라서 서버측에서 전송할지 말지를 판단한다. window size가 MSS보다 클때만 보내주고, 만약 작다면 클라이언트 측에 window size가 적절크기 이상이 될 때 까지 wait를 하게된다. 그렇기에 데이터 전송 속도는 클라이언트 측의 Read 속도와 밀접한 관계가 있다. 클라이언트의 Read 속도가 서버 전송 속도보다 느리다면 window size가 작다는 이유로 데이터 전송이 지연된다.