본문 바로가기
개발공부 개발새발/Network

Network) 데이터 송수신

by 휴일이 2023. 7. 27.

데이터 송수신

→ 애플리케이션이 write 를 호출하여 송신 데이터를 프로토콜 스택에 건네주는 것부터 시작한다.

프로토콜 스택의 특징

  • 프로토콜 스택은 받은 데이터의 내용에 무엇이 쓰여있는지 알지 못한다.
    • 해당 길이만큼 바이너리 데이터가 1바이트씩 차례대로 나열되어있다고 생각한다.
  • 받은 데이터를 바로 송수신하지 않고 어느정도 데이터를 저장하고 나서 송수신 동작을 한다. → 받은 데이터를 곧바로 보낸다면 작은 패킷을 많이 보낼 수도 있다. 비효율
    • 일단 내부에 있는 송신용 버퍼 메모리에 저장한다.
    • 애플리케이션이 다음 데이터를 건네주기를 기다린다.

어떻게 판단해서 데이터를 보내나요?

  1. 한 패킷에 저장할 수 있는 데이터의 크기
  2. 타이밍

한 패킷에 저장할 수 있는 데이터의 크기

| MTU | 한 패킷, 운반할 수 있는 데이터의 최대 길이(1500바이트) 패킷 맨 앞 부분에 헤더가 포함되어 있다. | | --- | --- | | MSS | 헤더를 제외한 하나의 패킷으로 운반할 수 있는 데이터 최대 길이 |

MSS 에 가까운 길이에 이르기까지 데이터를 저장하고 송신하면 패킷이 잘게 나누어질 걱정 X

타이밍

  • 프로토콜 스택은 내부에 타이머가 있어서 일정 시간 이상 경과하면 패킷을 송신
종류 장점 단점
데이터 크기 패킷 길이가 길어져 네트워크 이용 효율 상승 버퍼에 머무는 시간 만큼 송신 동작 지연
타이밍 지연이 적다 이용 효율이 떨어짐

결론

  • TCP 프로토콜 사양에 절충에 관한 규정은 없다.
  • 프로토콜 스택을 만드는 개발자에게 맡겨져 있다.
  • 프로토콜 스택에만 맡긴다면 좋지 않은 일이 벌어질 수 있으니, 애플리케이션에서 송신 타이밍을 제어할 수도 있다.
    • 브라우저와 같은 대화영 애플리케이션은 버퍼에 머무는 부분 만큼 응답 시간이 지연된다.
    • 보통 버퍼에 머물지 않고 바로 송신하는 옵션을 이용한다.

데이터 분할

  • 폼을 사용해서 긴 데이터를 보낼 때는 한 개의 패킷에 모든 데이터가 안 들어갈 수도 있다.
    • 송신 버퍼에 들어있는 데이터를 맨 앞부터 차례대로 MSS 크기에 맞게 분할한다.
    • 분할 조각을 하나씩 패킷에 넣어 송신한다.

패킷 도착 확인

TCP 에는 송신 패킷이 상대에게 올바르게 도착했는지 확인하고, 도착하지 않았으면 다시 송신하는 기능이 있다.

  1. TCP 담당이 데이터를 조각으로 분할할 때 조각이 통신 개시부터 따져서 몇 번째 바이트인지 세어둔다.
  2. 조각을 송신할 때 세어둔 값을 TCP 헤더에 기록한다.
    1. 시퀀스 번호 *시퀀스 번호는 항상 난수를 바탕으로 산출한다. 항상 1부터 시작한다고 예측하면 해킹 우려가 있다.
  3. 송신하는 데이터의 크기도 수신측에 전달한다.
    1. 패킷 전체길이 - 헤더 길이 빼면 산출이 가능하므로 따로 기록은 안 함

수신 확인 응답

  1. 수신 측은 이전 수신 데이터와 합쳐 데이터를 몇 번째 바이트까지 수신한 것인지 계산한다.
  2. 그 값을 TCP 헤더의 ACK 번호에 기록하여 송신측에 알린다.

양방향 데이터가 흐르는 경우

→ 사실 클라이언트와 서버가 데이터가 왔다갔다 하는 과정이 있기 때문에, 이런 식으로 데이터가 움직인다.

  1. 클라이언트가 데이터 시퀀스 초기값을 서버에 통지한다.
  2. 서버에서 다음을 산출하여 통지한다.
    1. 초기값으로 ACK 번호
    2. 데이터 시퀀스 초기값
  3. 클라이언트도 서버에서 받은 시퀀스 번호의 초기값으로부터 ACK 번호를 산출하여 서버에 반송한다.

TCP는 이 방법으로 상대가 데이터를 받은 것을 확인한다. 확인할 때까지 송신 패킷을 송신용 버퍼 메모리 영역에 보관해둔다. 송신한 데이터에 대응하는 ACK 번호가 상대로부터 돌아오지 않으면 패킷을 다시 보낸다.

장점

  • 네트워크 어디에서 오류가 발생했더라도 그것을 전부 검출하여 회복처리(패킷을 다시 보냄)할 수 있다.
  • 그래서 다른 곳에서 오류를 회복조치 할 필요 없다.
  • 오류를 검출하면 그 패킷을 버리기만 하면 된다.

→ TCP는 몇 번 다시 보낸 후 회복의 전망이 없는 것으로 보인다면 데이터 송신을 강제로 종료하고 애플리케이션에 오류를 통지한다.

 

 

✅ 시퀀스 번호와 ACK 번호로 패킷이 수신측에 도착한 것을 확인한다.

 

 

 

타임아웃 값

ACK 번호가 돌아오는 것을 기다리는 대기 시간

  • 네트워크가 혼잡하면 ACK 번호가 돌아오는 것이 지연된다.
  • 이를 예측하여 대기시간을 어느 정도 길게 설정해야 한다.
  • 안 그러면 ACK 번호가 되돌아오기 전에 다시 보내는 사태가 된다.

→ TCP 는 대기 시간을 동적으로 변경한다. ACK 번호가 돌아오는 시간을 기준으로 대기 시간을 판단하는 것!

윈도우 제어 방식

한 개의 패킷을 보낸 후 ACK 번호를 기다리지 않고 차례대로 연속해서 복수의 패킷을 보내는 법 → ACK 번호가 돌아올 때까지 시간이 낭비되지 않는다.

주의할 점

ACK 번호를 기다리지 않고 차례로 패킷을 보낸다면, 수신 측의 능력을 초과하여 패킷을 보낼 수도 있다.

그래서 ?

  1. 수신 측에서 송신 측에 수신 가능한 데이터의 양을 통지한다.
  2. 수신 측은 이 양을 초과하지 않도록 송신 동작을 실행한다.
  3. 수신 버퍼에 빈 부분이 생기면 그 분량만큼 수신 데이터의 양을 늘린다.
    1. TCP 헤더의 윈도우 필드에서 이것을 송신측에 알린다.
    2. 수신 가능한 데이터 양의 최대 값을 윈도우 사이즈 라고 한다.(TCP 정밀 조정 매개변수)

윈도우 통지 타이밍

→ 수신측에서 애플리케이션에 데이터를 건네주고 수신 버퍼에 빈 영역이 늘어났을 때 송신 측에 통지 ACK 번호는 수신 측에서 데이터를 받았을 때 내용을 조사하여 정상 수신을 확인할 수 있는 경우에만 송신 측에 보낸다. 즉, 데이터 수신 즉시 보낸다.

수신 측은 ACK 번호나 윈도우를 통지할 때 소켓을 바로 보내지 않고 잠시 기다린다. 기다리는 사이 다음 통지 동작이 일어나면 양쪽을 상승시켜 한 개의 패킷으로 묶어 보낸다!

  • 복수의 ACK 번호 통지가 연속해서 일어난 경우
  • 윈도우 통지가 연속한 경우

→ 도중을 생략하고 최후의 것만 통지한다.

HTTP 응답 메시지 수신

  1. 프로토콜 스택이 수신 버퍼에서 수신 데이터를 추출해서 애플리케이션에 건넴
  2. 수신 버퍼에 데이터가 들어가지 않으니 수신 버퍼에서 수신 데이터를 추출하여 애플리케이션에 건네주는 작업을 잠시 보류
  3. 서버에서 응답 메시지 패킷이 도착했을 때 그것을 수신하여 애플리케이션에 건네줌

프로토콜 스택이 데이터를 수신하는 동작

  1. 수신 데이터 조각과 TCP 헤더를 조사, 도중에 데이터가 누락되었는지 검사.
  2. 문제가 없으면 ACK 번호 반송
  3. 데이터 조각을 수신 버퍼에 일시 보관
  4. 조각을 연결해서 데이터를 원래 모습으로 복원
  5. 애플리케이션에 건네줌
    1. 수신 데이터를 애플리케이션이 지정한 메모리 영역에 옮겨 기록
    2. 애플리케이션에 제어 넘김
728x90

'개발공부 개발새발 > 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