25.[Network] 이해하면 인생이 바뀌는 TCP 송수신 원리
TCP/IP 연결 : 3-Way Handshake
PC#1 -- L2 -- 라우터 -- 인터넷 -- 라우터 -- L2 -- 서버
TCP 연결을 했다치고 파일을 다운로드 받는 상황을 예로 들어보자
송신: 서버쪽에서 파일 하나를 가지고 있고 클라이언트가 달라고 한다
<서버 상황>
서버 프로그램이 작동을 하고 있다 거기 소켓이 하나 열려 있어서 클라이언트랑 통신을 하고 있다
- 서버는 프로세스다
- 소켓의 본질은 파일이다
- RWX = 프로세스가 파일에 대고 할 수 있는 것
- 읽던지 쓰던지
RWX -> Read : Receive -> Write : Send
파일 시스템으로 파일 관리가 된다
↕
드라이버
↕
HDD 하드디스크안에 파일이 들어있다
- 유저보드쪽에 Memory를 할당한다
- 파일의 크기가 1.4MB로 크다고 가정한다
- 예를들어 64kB만큼 끊어서 메모리에 적재를 한다
파일에서 데이터를 읽어올 때 통째로 한번에 읽어오는 게 아니라 작게 끊어서 읽어온다
소켓은 TCP/IP를 추상화한 것
- 소켓에서 분해가 일어난다
- TCP 쪽에 버퍼가 있다
메모리의 다른 이름은 버퍼라고 한다
Buffer #1에서 Buffer #2로 copy한다
Buffered I/O : 버퍼간의 입출력
- TCP가 버퍼(메모리)를 가지고 있다가 IP쪽으로 내려갈 때 잘게 쪼갠다 -> Segment
예시) 직소퍼즐
- 1.4MB의 직소퍼즐 파일이 있다고 가정해보자
- 직소퍼즐 4개가 64kB라고 해보자
- 버퍼#1(메모리)에 직소퍼즐 4개가 쌓인다
- 버퍼#2로 copy 한다
- TCP->IP: 세그먼트로 분해하면서 번호를 붙인다 1, 2, 3, 4
- Packet(택배박스) 하나에 세그먼트(번호) 하나를 넣는다
- 택배를 아저씨에게 전달: 아저씨는 내용물에 관심이 없음 트럭 안에 집어넣음
- NIC로 내려옴: Frame = 트럭
- 목적지?
- 택배는 트럭을 갈아탄다!
- 논리적으론 패킷이 엔드포인트 끝단에서 끝단으로 가지만 패킷이 프레임화되서 갈 때는 프레임이 생겼다 사라졌다 몇번이고 반복한다
도착하는 곳: 클라이언트!
- 클라언트도 프로세스다
- File I/O Buffer : 파일에 연결된 버퍼가 있다
TCP Buffer : TCP도 버퍼가 있다
택배기사님이 트럭(Frame)에서 패킷을 꺼낼 때 Frame은 없어진다
- Decapsulation
- 패킷 안에서 Segment를 꺼낸다
- IP에서 패킷을 까서 TCP에서 Segment가 나온다
- 1번 직소퍼즐 세그먼트가 TCP Buffer에 가서 붙는다
- 대략 2개정도 세그먼트가 TCP에 오면 조립을 한다
- ACK(Acknowledgment): "잘 수신했다!" 라고 알리는 것
- 1번 2번을 보내고 Wait
- ACK#3를 기다린다
- 잘갔구나 -> 그 때 3번을 보낸다
-> 속도지연 발생
TCP가 UDP보다 느리다
- 기다리다가 느려지는 것!
TCP Buffer의 크기:
- Window Size: 수신측에서 세그먼트 조립해서 집어넣을 수 있는 공간
ACK 안에 Window Size를 포함하고 있다
ACK#3가 와서 3번을 전송할까? 말까?
- Window Size를 보니까 Segment가 들어갈 공간이 없으면 안 보냄
- 수신(받는 쪽)측의 Window Size > MSS(Maximum Segment Size)
- Yes -> 보냄
- No -> Wait
- 수신쪽의 TCP Buffer는 계속 채워진다
- 다 채워지면 File I/O로 보내야한다
- Read (Receive) 속도 > Network 수신
- Read 속도가 더 느리다면 TCP 버퍼의 여유가 사라진다
- Window Size: 여유 공간
- 여유가 없으면 Window Size가 없어서 못보낸다
- Window Size를 파악하면 어플리케이션의 네트워크 문제를 파악할 수 있다
- 네트워크에서 장애원인을 찾지 말고 프로그램(Client Process)에서 찾아야한다