[CS 기초] 네트워크

Sohyeon Bak·2022년 6월 25일
0

개발 책

목록 보기
10/18
post-thumbnail

'성공과 실패를 결정하는 1%의 네트워크 원리' 책을 바탕으로 정리한 내용입니다.

03. 데이터를 송·수신한다

프로토콜 스택에 HTTP 리퀘스트 메시지를 넘긴다

connect에서 애플리케이션에 제어가 되돌아오면 데이터 송·수신 동작이 되고 애플리케이션이 write를 호출해 송신데이터를 프로토콜 스택에 건네주고 이것을 받은 프로토콜 스택이 송신 동작을 실행한다.

  • 프로토콜 스택은 데이터 내용을 알지 못함
  • 데이터 길이 만큼만 바이너리 데이터가 1바이트씩 차례로 나열되고 있다고만 인식

🏷 프로토콜 스택의 송신 동작

  • 받은 데이터를 바로 송신하는 것이 아니라 버퍼 메모리 영역에 저장 후 애플리케이션에서 다음 데이터를 건네주기를 기다림
    → 기다리는 이유는 한꺼번에 송신 의뢰하는 경우도 있고, 1바이트나 1행씩 건네주는 방법도 있어서 프로토콜 스택에서 길이를 제어할 수 없다.
    데이터 길이를 알지도 못한채 받아온 데이터를 바로 보내주면 네트워크 이용 효율에 문제가 생김

  • 송신 동작의 판단 요소

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

      • MTU 매개 변수
        : 한 패킷으로 운반할 수 있는 디지털 데이터의 최대 길이,
        이더넷에서는 1,500바이트
      • MSS
        : 패킷의 헤더를 제외하고 하나의 패킷으로 운반할 수 있는 데이터의 최대 길이,
        MSS를 초과하거나 MSS에 가까운 길이에 이르기 까지 데이터를 저장하고 송신동작을 하면 패킷을 잘게 나눌 걱정할 필요 없다.
    • 타이밍
      : 송신 속도가 느려지는 경우 버퍼에 데이터가 모이지 않아도 적당한 곳에서 송신 동작 실행,
      프로토콜 스택의 내부 타이머로 일정 시간 이상 경과 하면 패킷을 송신

→ 전자를 중시할 경우 패킷 길이가 길어져 네트워크 이용 효율 높아지지만 버퍼에 머무는 시간 만큼 송신 동작이 지연 될 수 있음.
→ 후자를 중시할 경우 지연은 적어지지만 이용 효율이 떨어질 수 있음

데이터가 클 때는 분활하여 보낸다

HTTP 리퀘스트 메세지 중 한 개의 패킷을 넘어가는 긴 메세지 일 경우

  1. 송신 버퍼에 들어있는 데이터를 맨 앞부터 차례대로 MSS의 크기에 맞게 분할
  2. 분할된 조각을 한개씩 패킷에 넣어 송신한다.
    • 패킷 맨 앞에는 TCP 헤더를 부가하고 송/수신처 포트번호 등 중요한 항목을 기록
  3. IP 담당 부분에 건네주어 송신 동작을 실행한다.

ACK 번호를 사용하여 패킷이 도착했는지 확인한다.

TCP에는 송신한 패킷이 상대에게 올바르게 도착했는지 확인하는 동작으로 넘어간다.

🏷 확인 방법에 대한 개념

  • 데이터를 조각으로 분할할 때 몇 번째 바이트에 해당하는지 기록
  • 시퀀스 번호
    : 데이터의 조각을 송신할 때 세어둔 값을 TCP 헤더에 기록하는 것
    • 패킷 전체의 길이에서 헤더의 길이를 빼면 크기를 계산 할 수 있기 때문에 크기를 따로 수신측에 알리지는 않음
  • 누락이 없는 것을 확인하면 수신측은 그 이전에 수신한 데이터와 함쳐서 데이터를 몇 번째 바이트까지 수신한 것인지 계산
  • 그 값은 TCP 헤어의 ACK 번호에 기록
    → 수신응답 확인 과정

📌
시퀀스 번호는 1부터 시작하지 않고 난수로 시작해 예측할 수 없게 만듦.
그러나 난수로 지정하게 되면 초기값을 알 수 없는 문제가 생김으로 접속 동작 부분에서 SYN이라는 제어비트를 1로 하여 초기값을 통지한다.
→ SYN에 1를 설정할 때 시퀀스 번호에도 값을 설정하게 되어 시퀀스 번호의 값이 초기값을 나타낸다.

📌
TCP의 데이터 송·수신 동작은 양방향이므로 클라이언트에서 서버로 향하는 데이터 흐름과 서버에서 클라이언트로 향하는 두가지 데이터 흐름이 있어서 각각 대응해줘야한다.

🏷 클라이언트→서버

  • 시퀀스 번호는 클라이언트 측에서 산출하여 데이터와 함께 서버에 통지
  • 서버측에서 ACK 번호를 산출 후 클라이언트에 반송

🏷 서버→클라이언트

  • 데이터에 관한 시퀀스 번호는 서버에서 산출해 데이터와 함께 클라이언트에 통지
  • 클라이언트 측에서 ACK 번호를 산출해 서버에 응답

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

  • 오류가 발생해도 전부 검출해 회복처리를 취할 수 있고
  • 다른 곳에서 오류를 위한 회복 조치를 할 필요 없다.

패킷 평균 왕복 시간으로 ACK 번호의 대기 시간을 조정

타임아웃 값
: ACK 번호가 돌아오는 것을 기다리는 시간

  • 대기 시간을 적정하게 두지 않으면 ACK 번호의 반송이 지연됨으로 혼잡해진다.
  • 대기시간을 무조건 길게 하면 패킷을 다시 보내는 동작이 지연되어 속도 저하가 생길 수 있다
    → TCP는 대기시간을 동적으로 변경하는 방법을 취한다

윈도우 제어 방식으로 효율적으로 ACK 번호를 관리한다

윈도우 제어
: 한 개의 패킷을 보낸 후 ACK 번호를 기다리지 않고 차례대로 연속해서 복수의 패킷을 보내는 방법

  • 핑퐁 방식
    : ACK 번호를 기다리지 않고 차례로 패킷을 보내면 수신측의 능력을 초과해 패킷을 보내는 사태가 생길 수 있음
    데이터 속도가 애플리 케이션에서 건네주는 속도보다 빠르면 수신 버퍼에 데이터가 넘처흘리게 되는 것을 수신측의 능력을 초과한다는 의미

  • 윈도우 필드
    : 수신 처리가 끝나고 수신 버페어 빈 부분이 생기면 그 분량만큼 수신할 수 있는 데이터 양을 늘려서 TCP 헤더의 윈도우 필드에서 송신측에 알린다.

  • 윈도우 사이즈
    : 수신가능한 데이터 양의 최대값

ACK 번호와 윈도우를 합승한다

🏷 윈도우 통지와 ACK 번호

  1. 송신측에서 보낸 데이터가 수신측에 도착해 정상완료
  2. ACK 번호를 송신측에 통지 후 데이터를 애플리케이션에 건네주고 윈도우를 송신측에 동지하는 상태
  3. 수신측은 잠시 기다리는데 그 사이 다음 통지 동작이 일어나면 양쪽을 상승시켜 한개의 패킷으로 묶어서 보냄
  4. ACK 번호와 윈도우를 한개의 패킷에 합승시켜 통지해 패킷의 수를 줄일 수 있다.

HTTP 응답 메시지를 수신한다

브라우저는 리퀘스트 메시지를 송신해 달라고 의뢰하고, 응답 메세지를 받기 위해 read 프로그램을 호출한다.
read를 경유해 프로토콜 스택에 제어가 넘어가고, 프로토콜 스택이 움직인다.
데이터를 임시 보관하는 수신 버퍼를 사용한다.

  • 프로토콜 스택
    : 수신 버퍼에서 수신 데이터를 추출해 애플리케이션에 건네준다
profile
정리하고 기억하는 곳

0개의 댓글