tcp에서 제공하는 세가지 중요한 기능이 reliable transfer, flow control, congestion control이라는 서비스에 대해서 이야기할거야 flow control은 너무나 직관적이고 이해하기 쉬워요.
아직까지 이야기 안한거 뭐냐면, 얼만큼 이걸 쏟아부을건지에 대해서야. 얼마만큼의 속도로 윈도우 사이즈를 정할거냐고. 이거는 결국 리시버 버퍼로 보내는 것이기 때문에 리시버의 받아줄 수 있는 능력 capacity가 얼마나 되는지 sender 속도를 조절해야해. 리시버가 내 버퍼상태를 피드백을 주면 내가 그만큼 보내면 되는거잖아. 이게 방금 얘기했떤 리시버 버퍼에요 이게 예를들면 꽉차있어. 그럼 센더가 보내봤자 다 유실되겠죠. 공간이 많으면 많이 보내도 될거고. read()로 불려가지 않아서…
buffer의 남은 공간보다 작게 보내면 되겠죠. 아주 직관적이에요. 리시버는 자기 자신의 리시브 버퍼의 남은 공간의 크기를 알 고 있죠. ack보낼때 내 공간 리시브 버퍼라는 헤더필드가 있어서 거기 적어서 보내주면 돼요. 너무나 단순하죠. 이게 끝이에요.
리시버가 리시브버퍼에 남은 공간 없어서 tcp 헤더에 넣어서 보냈어. 센더가 0을 받았어. 어 공간없어? 그럼 안보낼게 했어. 그럼 리시버 입장에서는 센드버퍼 비어있으니까, 이제 보낼게 없는거야. 공간이 생겨도 보낼게 없어. 리시버 → 센더 방향으로 날라올 세그먼트가 없어. 세그먼트를 날릴 이유가 없어.
그럼 어떻게 해야돼? 리시브 버퍼에 공간이 없다고 와도, 세그먼트를 항상 날려보는거야. 1바이트짜리 데이터만 해서 보내는거야. 왜냐면 리시브 버퍼에 공간 없다매. 그럼 유실될 가능성이 높잖아 그니까 찔러볼 용도로 1바이트짜리 아주 작은 최소한의 데이터만 찔러 보는거야.
application layer에서 메세지를 많이 생산하지 않는다면?
segment를 얼마나 자주 만들어서 보내야될지 의사결정을 해줘야돼. 메세지를 생산할 때까지 기다릴거야? 아니면 오버헤드더라도 메세지를 보낼거야?
해결책1:
(리시버는 쬬금 기다렸다가 모아서 ack 보낸다 정도~)