데이터 송수신
→ 애플리케이션이 write 를 호출하여 송신 데이터를 프로토콜 스택에 건네주는 것부터 시작한다.
프로토콜 스택의 특징
- 프로토콜 스택은 받은 데이터의 내용에 무엇이 쓰여있는지 알지 못한다.
- 해당 길이만큼 바이너리 데이터가 1바이트씩 차례대로 나열되어있다고 생각한다.
- 받은 데이터를 바로 송수신하지 않고 어느정도 데이터를 저장하고 나서 송수신 동작을 한다. → 받은 데이터를 곧바로 보낸다면 작은 패킷을 많이 보낼 수도 있다. 비효율
- 일단 내부에 있는 송신용 버퍼 메모리에 저장한다.
- 애플리케이션이 다음 데이터를 건네주기를 기다린다.
어떻게 판단해서 데이터를 보내나요?
- 한 패킷에 저장할 수 있는 데이터의 크기
- 타이밍
한 패킷에 저장할 수 있는 데이터의 크기
| MTU | 한 패킷, 운반할 수 있는 데이터의 최대 길이(1500바이트) 패킷 맨 앞 부분에 헤더가 포함되어 있다. | | --- | --- | | MSS | 헤더를 제외한 하나의 패킷으로 운반할 수 있는 데이터 최대 길이 |
MSS 에 가까운 길이에 이르기까지 데이터를 저장하고 송신하면 패킷이 잘게 나누어질 걱정 X
타이밍
- 프로토콜 스택은 내부에 타이머가 있어서 일정 시간 이상 경과하면 패킷을 송신
종류 | 장점 | 단점 |
데이터 크기 | 패킷 길이가 길어져 네트워크 이용 효율 상승 | 버퍼에 머무는 시간 만큼 송신 동작 지연 |
타이밍 | 지연이 적다 | 이용 효율이 떨어짐 |
결론
- TCP 프로토콜 사양에 절충에 관한 규정은 없다.
- 프로토콜 스택을 만드는 개발자에게 맡겨져 있다.
- 프로토콜 스택에만 맡긴다면 좋지 않은 일이 벌어질 수 있으니, 애플리케이션에서 송신 타이밍을 제어할 수도 있다.
- 브라우저와 같은 대화영 애플리케이션은 버퍼에 머무는 부분 만큼 응답 시간이 지연된다.
- 보통 버퍼에 머물지 않고 바로 송신하는 옵션을 이용한다.
데이터 분할
- 폼을 사용해서 긴 데이터를 보낼 때는 한 개의 패킷에 모든 데이터가 안 들어갈 수도 있다.
- 송신 버퍼에 들어있는 데이터를 맨 앞부터 차례대로 MSS 크기에 맞게 분할한다.
- 분할 조각을 하나씩 패킷에 넣어 송신한다.
패킷 도착 확인
TCP 에는 송신 패킷이 상대에게 올바르게 도착했는지 확인하고, 도착하지 않았으면 다시 송신하는 기능이 있다.
- TCP 담당이 데이터를 조각으로 분할할 때 조각이 통신 개시부터 따져서 몇 번째 바이트인지 세어둔다.
- 조각을 송신할 때 세어둔 값을 TCP 헤더에 기록한다.
- 시퀀스 번호 *시퀀스 번호는 항상 난수를 바탕으로 산출한다. 항상 1부터 시작한다고 예측하면 해킹 우려가 있다.
- 송신하는 데이터의 크기도 수신측에 전달한다.
- 패킷 전체길이 - 헤더 길이 빼면 산출이 가능하므로 따로 기록은 안 함
수신 확인 응답
- 수신 측은 이전 수신 데이터와 합쳐 데이터를 몇 번째 바이트까지 수신한 것인지 계산한다.
- 그 값을 TCP 헤더의 ACK 번호에 기록하여 송신측에 알린다.
양방향 데이터가 흐르는 경우
→ 사실 클라이언트와 서버가 데이터가 왔다갔다 하는 과정이 있기 때문에, 이런 식으로 데이터가 움직인다.
- 클라이언트가 데이터 시퀀스 초기값을 서버에 통지한다.
- 서버에서 다음을 산출하여 통지한다.
- 초기값으로 ACK 번호
- 데이터 시퀀스 초기값
- 클라이언트도 서버에서 받은 시퀀스 번호의 초기값으로부터 ACK 번호를 산출하여 서버에 반송한다.
TCP는 이 방법으로 상대가 데이터를 받은 것을 확인한다. 확인할 때까지 송신 패킷을 송신용 버퍼 메모리 영역에 보관해둔다. 송신한 데이터에 대응하는 ACK 번호가 상대로부터 돌아오지 않으면 패킷을 다시 보낸다.
장점
- 네트워크 어디에서 오류가 발생했더라도 그것을 전부 검출하여 회복처리(패킷을 다시 보냄)할 수 있다.
- 그래서 다른 곳에서 오류를 회복조치 할 필요 없다.
- 오류를 검출하면 그 패킷을 버리기만 하면 된다.
→ TCP는 몇 번 다시 보낸 후 회복의 전망이 없는 것으로 보인다면 데이터 송신을 강제로 종료하고 애플리케이션에 오류를 통지한다.
✅ 시퀀스 번호와 ACK 번호로 패킷이 수신측에 도착한 것을 확인한다.
타임아웃 값
ACK 번호가 돌아오는 것을 기다리는 대기 시간
- 네트워크가 혼잡하면 ACK 번호가 돌아오는 것이 지연된다.
- 이를 예측하여 대기시간을 어느 정도 길게 설정해야 한다.
- 안 그러면 ACK 번호가 되돌아오기 전에 다시 보내는 사태가 된다.
→ TCP 는 대기 시간을 동적으로 변경한다. ACK 번호가 돌아오는 시간을 기준으로 대기 시간을 판단하는 것!
윈도우 제어 방식
한 개의 패킷을 보낸 후 ACK 번호를 기다리지 않고 차례대로 연속해서 복수의 패킷을 보내는 법 → ACK 번호가 돌아올 때까지 시간이 낭비되지 않는다.
주의할 점
ACK 번호를 기다리지 않고 차례로 패킷을 보낸다면, 수신 측의 능력을 초과하여 패킷을 보낼 수도 있다.
그래서 ?
- 수신 측에서 송신 측에 수신 가능한 데이터의 양을 통지한다.
- 수신 측은 이 양을 초과하지 않도록 송신 동작을 실행한다.
- 수신 버퍼에 빈 부분이 생기면 그 분량만큼 수신 데이터의 양을 늘린다.
- TCP 헤더의 윈도우 필드에서 이것을 송신측에 알린다.
- 수신 가능한 데이터 양의 최대 값을 윈도우 사이즈 라고 한다.(TCP 정밀 조정 매개변수)
윈도우 통지 타이밍
→ 수신측에서 애플리케이션에 데이터를 건네주고 수신 버퍼에 빈 영역이 늘어났을 때 송신 측에 통지 ACK 번호는 수신 측에서 데이터를 받았을 때 내용을 조사하여 정상 수신을 확인할 수 있는 경우에만 송신 측에 보낸다. 즉, 데이터 수신 즉시 보낸다.
수신 측은 ACK 번호나 윈도우를 통지할 때 소켓을 바로 보내지 않고 잠시 기다린다. 기다리는 사이 다음 통지 동작이 일어나면 양쪽을 상승시켜 한 개의 패킷으로 묶어 보낸다!
- 복수의 ACK 번호 통지가 연속해서 일어난 경우
- 윈도우 통지가 연속한 경우
→ 도중을 생략하고 최후의 것만 통지한다.
HTTP 응답 메시지 수신
- 프로토콜 스택이 수신 버퍼에서 수신 데이터를 추출해서 애플리케이션에 건넴
- 수신 버퍼에 데이터가 들어가지 않으니 수신 버퍼에서 수신 데이터를 추출하여 애플리케이션에 건네주는 작업을 잠시 보류
- 서버에서 응답 메시지 패킷이 도착했을 때 그것을 수신하여 애플리케이션에 건네줌
프로토콜 스택이 데이터를 수신하는 동작
- 수신 데이터 조각과 TCP 헤더를 조사, 도중에 데이터가 누락되었는지 검사.
- 문제가 없으면 ACK 번호 반송
- 데이터 조각을 수신 버퍼에 일시 보관
- 조각을 연결해서 데이터를 원래 모습으로 복원
- 애플리케이션에 건네줌
- 수신 데이터를 애플리케이션이 지정한 메모리 영역에 옮겨 기록
- 애플리케이션에 제어 넘김
'개발공부 개발새발 > Network' 카테고리의 다른 글
Network ) 이더넷 (0) | 2023.07.27 |
---|---|
Network) 연결 끊기와 데이터 송수신 요약 (0) | 2023.07.27 |
Network) 서버에 접속하자! (0) | 2023.07.26 |
Network) Protocol Stack (0) | 2023.07.25 |
DNS ) DNS 서버 (0) | 2023.07.25 |