[성공과 실패를 결정하는 1%의 네트워크 원리] 2장

'성공과 실패를 결정하는 1%의 네트워크 원리' 스터디를 진행하며 정리한 내용이다.


01 소켓을 작성한다.

  1. 프로토콜 스택의 내부 구성

    KakaoTalk_20210929_220830699

    • 네트워크 애플리케이션

      • 브라우저, 메일러, 웹 서버, 메일 서버 등의 프로그램
      • 여기부터 아래로 향하여 데이터 송, 수신 등의 일을 의뢰함.
      • 브라우저뿐만 아니라 어떤 애플리케이션도 송, 수신 동작은 거의 비슷함.
    • Socket 라이브러리

      • DNS 서버에 조회하는 동작을 실행하는 리졸버가 내장되어 있음. (1장에서 설명함)
    • 프로토콜 스택

      • TCP

        • 브라우저나 메일 등의 일반적인 애플리케이션은 TCP를 사용하여 데이터를 송, 수신함.
      • UDP

        • DNS 서버에 대한 조회 등에서 짧은 제어용 데이터를 송, 수신하는 경우 UDP를 사용함.
      • IP

        • 패킷 송, 수신 동작을 제어하는 부분.
        • 인터넷에서 데이터를 운반할 때는 데이터를 작게 나누어 패킷이라는 형태로 운반하는데, 이 패킷을 통신 상대까지 운반하는 것이 IP의 주 역할.
        • ICMP - 패킷을 운반할 때 발생하는 오류를 통지하거나 제어용 메시지를 통지할 때 사용함.
        • ARP - IP 주소에 대응하는 이더넷의 MAC 주소를 조사할 때 사용함.
      • LAN 드라이버

        • LAN 어댑터의 하드웨어를 제어함.
      • LAN 어댑터

        • 실제 송, 수신 동작, 즉 케이블에 대해 신호를 송, 수신하는 동작을 실행함.

  1. 소켓의 실체는 통신 제어용 제어 정보

    • 프로토콜 스택은 내부에 제어 정보를 기록하는 메모리 영역을 가지고 있음.

      • 여기에 통신 동작을 제어하기 위한 제어 정보를 기록함.
      • 대표적으로 통신 상대의 IP 주소는 무엇인가, 포트 번호는 몇 번인가, 통신 동작이 어떤 진행 상태에 있는가
      • 소켓은 개념적인 것이라 실체가 없으므로 굳이 말하자면 이 제어 정보가 소켓의 실체라고 할 수 있다!
        또는 제어 정보를 기록한 메모리 영역이 소켓의 실체라고 생각해도 좋다.
    • 프로토콜 스택은 이 제어 정보를 참조하면서 동작함.

      • 소켓에는 응답이 돌아오는지의 여부와 송신 동작 후의 경과 시간 등이 기록되어 있음.
      • 프로토콜 스택은 이 정보를 보고 포기하거나 다시 보내는 동작을 실행함.
    • 소켓에는 통신 동작을 제어하기 위한 여러 가지 제어 정보가 기록되어 있다.

      • 프로토콜 스택은 이것을 참조하여 다음에 무엇을 해야 하는지를 판단.
    • 윈도우의 경우 netstat 명령으로 소켓의 내용을 화면에 표시할 수 있다.

  1. Socket를 호출했을 때의 동작

    1. 소켓을 만드는 단계

      • socket을 호출하여 소켓을 만들 것을 의뢰하면 프로토콜 스택은 의뢰에 따라 한 개의 소켓을 만든다.
      • 프로토콜 스택이 최초로 하는 일은 소켓 한 개 분량의 메모리 영역을 확보하는 것.

        • 소켓의 제어 정보를 기록하는 메모리 영역은 처음부터 존재하는 것이 아니므로 먼저 그것을 확보해 두어야 한다.
    2. 소켓을 나타내는 디스크립터를 애플리케이션에 알려줌.

      • 애플리케이션은 이후 프로토콜 스택에 데이터 송, 수신 동작을 의뢰할 때 디스크립터를 통지한다.

02 서버에 접속한다

  1. 접속의 의미

    • 소켓을 만든 직후에 애플리케이션에서 데이터 송신 의뢰가 오면 프로토콜 스택은 어떻게 될까?

      • 만든 직후에는 아무 것도 기록되어 있지 않으므로 통신 상대가 누구인지도 모름.
      • 브라우저가 알고 있는 정보만으로는 부족.
      • 서버의 IP 주소나 포트 번호를 프로토콜 스택에 알리는 동작이 필요한데, 이것이 접속 동작의 한 가지 역할.
    • 그럼 서버측은 어떨까?

      • 서버측도 소켓이 만들어졌지만 통신 상대를 알 수 없음.
      • 클라이언트에서 정보를 알려서 통신하려는 클라이언트가 있다는 것을 서버측에 전달함.
      • 클라이언트측에서 서버측에 통신 동작의 개시를 전달하는 것도 접속 동작의 역할 중 하나.
    • 접속 동작의 첫 번째 동작은 통신 상대와의 사이에 제어 정보를 주고받아 소켓에 필요한 정보를 기록하고 데이터 송, 수신이 가능한 상태로 만드는 것.

      • 송, 수신하는 데이터를 일시적으로 저장하는 메모리 영역이 필요한데, 이 메모리 명역을 '버퍼 메모리'라고 부른다. 버퍼 메모리의 확보도 접속 동작을 할 때 실행되는데, 이것이 '접속' 한다는 동작의 의미.

  1. 맨 앞부분에 제어 정보를 기록한 헤더를 배치한다.

    • 제어 정보는 크게 두 종류가 있다.

      1. 클라이언트와 서버가 서로 연락을 절충하기 위해 주고받는 제어 정보.

        • 접속 동작뿐만 아니라 데이터를 송, 수신하는 동작이나 연결을 끊는 동작도 포함하여 통신 동작 전체에 어떤 정보가 필요한지 검토하여 내용을 TCP 프로토콜의 사양으로 규정하고 있다.
        • 제어 정보는 패킷의 맨 앞부분에 부가하는데 배치하는 곳부터 헤더라고 부른다.

          • 이더넷, IP에도 같은 제어 정보가 있고 헤더라고 부르기에 TCP 헤더, IP 헤더와 같이 알 수 있도록 써야함.
        • 헤더의 각 항목의 의미를 알면 통신 동작을 알았다고 해도 좋을 정도로 중요함.
      2. 소켓에 기록하여 프로토콜 스택의 동작을 제어하기 위한 정보.

        • 애플리케이션에서 통지되는 정보, 통신 상대로부터 받은 정보 등이 수시로 기록됨.
        • 소켓의 제어 정보는 프로토콜 스택의 프로그램과 일체화되어 있다고 해도 좋다.
        • 프로토콜 스택이 어떤 정보를 필요로 하는지는 프로토콜 스택을 만드는 사람에 따라 달라진다.
        • 소켓에 기록한 제어 정보는 상대측에서 볼 수 없다.

  1. 접속 동작의 실제

    • connect 호출에서 서버 IP 주소, 포트 번호를 쓰면 프로토콜 스택의 TCP 담당 부분에 전달된다.

      • TCP 담당 부분은 서버의 TCP 담당 부분과의 사이에 제어 정보를 주고받는다.
      • 단계는 다음과 같다.

        1. 데이터 송, 수신 동작의 개시를 나타내는 제어 정보를 기록한 헤더를 만든다.

          • 헤더에서 다수의 항목이 있는데 중요한 것은 송신처와 수신처의 포트 번호

            • 이를 통해 송신처가 되는 클라이언트측의 소켓과 수신처가 되는 서버측의 소켓을 지정할 수 있다.
          • 접속해야하는 소켓이 어느 것인지 확실히 하고 컨트롤 비트인 SYN을 1로 만든다.
        2. IP 담당 부분에 건네주어 송신하도록 의뢰한다.
        3. IP 담당 부분이 패킷 송신 동작을 실행하고 서버에 도착하면 서버측의 IP 담당 부분이 이것을 받고 TCP 담당 부분에 건네준다.

          • TCP 담당 부분이 TCP 헤더를 조사하여 수신처 포트 번호에 해당하는 소켓을 찾아낸다.
          • 해당하는 소켓이 발견되면 필요한 정보를 기록하고 접속 동작이 진행중이라는 상태가 된다.
        4. 이 과정이 끝나면 서버의 TCP 담당 부분은 응답을 돌려보낸다.
        5. 서버에서도 클라이언트와 마찬가지로 송신처, 수신처의 포트 번호나 SYN 비트 등을 설정한 TCP 헤더를 만든다.

          • ACK라는 컨트롤 비트도 1로 만든다.

            • 패킷을 받은 것을 알리기 위한 동작.
        6. TCP 헤더를 IP 담당 부분에 건네주어 클라이언트에 반송하도록 의뢰한다.
        7. 패킷이 클라이언트에 돌아오고 IP 담당 부분을 경유하여 TCP 담당 부분에 도착함.
        8. TCP 헤더를 조사하여 서버측의 접속 동작이 성공했는지 확인한다.

          • SYN이 1이면 접속 성공이므로 소켓에 서버의 IP 주소나 포트 번호 등과 함께 소켓에 접속 완료를 나타내는 제어 정보를 기록한다.
        9. 패킷이 도착한 것을 서버에 알리기 위해 ACK 비트를 1로 만든 TCP 헤더를 반송한다.
        10. 서버에 도착하면 접속 동작의 대화가 끝난다.
    • 송, 수신할 수 있는 상태가 되면 파이프와 같은 것으로 소켓이 연결되었다고 생각할 수 있다.

      • 실제로 무엇인가 연결된 것은 아니지만 이렇게 생각하는 것이 네트워크 업계의 습관
      • 이 파이프와 같은 것을 커넥션이라고 함.
      • close를 호출하여 연결을 끊을 때까지 계속 존재한다.
      • connect 실행이 끝나면 애플리케이션을 제어할 수 있게 된다.

03 데이터를 송, 수신한다

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

    • 데이터 송, 수신 동작은 애플리케이션이 write를 호출하여 송신 데이터를 프로토콜 스택에 건네주는 곳부터 시작된다.

      • 프로토콜 스택은 데이터의 내용이 무엇인지 알지 못한다.
      • 받은 데이터를 곧바로 송신하는 것이 아니라 자체 내부에 있는 송신용 버퍼 메모리 영역에 저장하고 애플리케이션이 다음 데이터를 건네주기를 기다린다.

        • 건네주는 데이터의 길이는 애플리케이션의 사정에 따라 결정되기에 받은 데이터를 곧바로 보내버리면 작은 패킷을 보낼 수도 있어 네트워크 이용 효율이 저하됨.
        • 어느 정도 데이터를 저장하고 송, 수신 동작을 하는데 정도는 OS의 종류나 버전에 따라 달라지나 다음과 같은 요소로 판단함.

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

            • MTU: 패킷 한 개로 운반할 수 있는 디지털 데이터의 최대 길이. 이더넷에서는 보통 1500바이트
            • MSS: 헤더를 제외하고 한 개의 패킷으로 운반할 수 있는 TCP 데이터의 최대 길이
          2. 타이밍

            • 애플리케이션의 송신 속도가 느려질 때 MSS에 가깝게 데이터를 저장하면 송신 동작이 지연되므로 적당한 곳에서 송신 동작을 실행해야 한다.
            • 프로토콜 스택 내부에 타이머가 있어서 일정 시간 이상 경과하면 패킷으로 송신함.
        • 전자를 중시하면 패킷 길이가 길어져서 네트워크의 이용 효율이 높아지지만 버퍼에 머무는 시간만큼 송신 동작이 지연될 우려가 있다.
        • 후자를 중시하면 지연은 적어지지만 이용 효율이 떨어진다.
        • 어떻게 판단해야 할지는 프로토콜 스택을 만드는 개발자에 맡겨져 있다.
      • 애플리케이션측에서도 송신 타이밍을 제어하는 여지를 남겨두었다.

        • '버퍼에 머물지 않고 바로 송신할 것' 이라고 옵션을 지정하면 프로토콜 스택은 버퍼에 머물지 않고 송신 동작을 실행한다.

  1. 데이터가 클 때는 분할하여 보낸다.

    • 긴 데이터를 보낼 경우 송신 버퍼에 저장된 데이터는 MSS의 길이를 초과하므로 다음 데이터를 기다릴 필요가 없다.
    • 송신 버퍼에 들어있는 데이터를 맨 앞부터 차례대로 MSS 크기의 맞게 분할하고, 분할한 조각을 한 개씩 패킷에 넣어 송신한다.

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

    • TCP에는 송신한 패킷이 상대에게 올바르게 도착했는지 확인하고, 도착하지 않았으면 다시 송신하는 기능이 있으므로 패킷을 송신한 후에는 확인 동작으로 넘어간다.
    • TCP 담당 부분은 데이터를 조각으로 분할할 때 조각이 통신 개시부터 따져서 몇 번째 바이트에 해당하는지 세어둔다.

      • 데이터 조각을 송신할 때 세어둔 값을 TCP 헤더에 기록하는데, 시퀀스 번호라는 항목에 해당됨.
    • 송신하는 데이터의 크기도 수신측에 전달하지만 여기에서는 헤더에 기록하여 수신측에 알리지 않는다.

      • 패킷 전체 길이 - 헤더 길이 = 데이터의 크기
      • 이 방법으로 크기를 산출한다.
    • 시퀀스 번호를 이용해 누락이 없는 것을 확인하면 수신측인 그 이전에 수신한 데이터와 합쳐서 몇 번째 바이트까지 수신한 것인지 계산하고, 그 값을 TCP 헤더의 ACK 번호에 기록하여 송신측에 알려준다.

      • ACK 번호를 되돌려주는 동작을 수신 확인 응답이라고 부른다.
    • 실제로 시퀀스 번호의 시작은 난수를 바탕으로 산출한 초기값임.

      • SYN이라는 제어 비트를 1로 하여 서버에 보낼 때 초기값을 통지함.
    • 이 흐름을 양방향으로 나타내려면 좌우를 역전시키면 된다.

      KakaoTalk_20210929_235842088

      KakaoTalk_20210930_000015267

    • TCP는 이 방법으로 상대가 데이터를 받은 것을 확인하는데, 확인할 때까지 송신한 패킷을 송신용 버퍼 메모리 영역에 보관해둔다. ACK 번호가 돌아오지 않으면 패킷을 다시 보낸다.
    • 이를 이용해 네트워크의 어디에서 오류가 발생했더라도 그것을 전부 검출하여 회복 처리(패킷을 다시 보내는 것)를 취할 수 있다. 또한 그렇기에 다른 곳에서 오류를 회복 조치할 필요가 없다.
    • TCP가 아무리 보내도 데이터가 도착하지 않는 경우 (케이블 분리, 서버 다운 등) 몇 번 다시 보낸 후 데이터 송신 동작을 강제로 종료하고 애플리케이션에 오류를 통지함.

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

    • ACK 번호가 돌아오는 것을 기다리는 시간을 타임아웃 값이라고 한다.
    • 대기 시간을 적절한 값으로 설정해야 하는데 간단하지 않다.

      • TCP는 ACK 번호가 돌아오는 시간을 계측해 두는데 지연되면 대응하여 대기 시간도 늘리고 반대로 ACK 번호가 곧바로 돌아오면 대기 시간을 짧게 설정한다.

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

    • ACK 번호가 돌아올 때까지의 시간 동안 아무 일도 하지 않고 기다리는 것은 시간 낭비
    • TCP는 윈도우 제어라는 방식에 따라 송신과 ACK 번호 통지의 동작을 실행함.

      • 한 개의 패킷을 보낸 후 ACK 번호를 기다리지 않고 차례대로 연속해서 복수의 패킷을 보내는 방법.
      • 수신측의 능력을 초과하여 패킷을 보내는 사태가 일어날 수 있다.

        • 수신측에서 송신측에 수신 가능한 데이터 양을 통지하고, 수신측은 이 양을 초과하지 않도록 송신 동작을 실행하는 방법으로 이를 피할 수 있다.

          KakaoTalk_20210930_001659647

        • 수신 버퍼에 빈 부분이 생기면 TCP 헤더의 윈도우 필드에 이것을 송신측에 알림. 수신 가능한 데이터 양의 최대값을 윈도우 사이즈라고 부름.

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

    • 이론 상으로 보면 송신측에 보낸 데이터가 수신측에 도착하여 수신 동작이 정상적으로 완료되었을 때 ACK 번호를 송신측에 통지한다. 잠시 후 데이터를 애플리케이션에 건네주었을 때 윈도우를 송신측에 통지하는 상태가 된다.

      • 수신측에서 송신측에 보내는 패킷이 많아져서 효율성이 저하됨.
    • 실제로는 수신측은 ACK 번호나 윈도우를 통지할 때 소켓을 바로 보내지 않고 잠시 기다린다. 기다리는 사이에 다음 통지 동작이 일어나면 양쪽을 상승시켜서 한 개의 패킷으로 묶어서 보낸다.

      • 복수의 ACK 번호 통지도 연속해서 일어나면 최후의 것만 통지함.
      • 윈도우 통지도 마찬가지.

  1. HTTP 응답 메시지를 수신한다.

    • 응답 메시지가 돌아오기를 기다리고 응답 메시지가 돌아오면 그것을 수신한다.
    • 응답 메시지를 받기 위해 read 프로그램을 호출함.

      • 프로토콜 스택은 수신 버퍼에서 수신 데이터를 추출하여 애플리케이션에 건네준다.
      • 응답 메시지가 올 때까지 시간이 걸리므로 잠시 보류한다.
      • 응답 메시지 패킷이 도착했을 때 그것을 수신하여 애플리케이션에 건네주는 작업을 재개한다.

04 서버에서 연결을 끊어 소켓을 말소한다.

  1. 데이터 보내기를 완료했을 때 연결을 끊는다.

    • 데이터 송, 수신을 종료하는 것은 애플리케이션이 송신해야 하는 데이터를 전부 송신 완료했다고 판단했을 때.

      • 웹이라면 브라우저가 리퀘스트 메시지를 보내고 서버가 응답하여 데이터 보내기에 서버측이 연결 끊기 단계에 들어감. (HTTP 1.1의 경우 클라이언트에서 연결 끊기 동작에 들어갈 수도 있다)
      • 클라이언트측이 데이터 보내기를 완료했다고 하는 식의 애플리케이션은 클라이언트측에서 끊기 단계에 들어감.
      • 어느 쪽에서 먼저 연결 끊기 단계에 들어가도 좋게 만들어져 있다.
    • 서버측에서 연결 끊기 단계에 들어갈 때

      KakaoTalk_20210930_221658537

      1. 서버측 Socket 라이브러리 close 호출
      2. 서버측 프로토콜 스택이 TCP 헤더를 만들고 연결 끊기 정보 설정

        • 컨트롤 비트의 FIN 비트 1 설정
      3. IP 담당 부분에 의뢰하여 클라이언트에 송신해 달라고 함

        • 이와 동시에 서버측의 소켓에 연결 끊기 동작에 들어갔다는 정보를 기록
      4. FIN에 1 설정한 TCP 헤더가 도착하면 클라이언트측 프로토콜 스택은 자신의 소켓에 서버측이 연결 끊기 동작에 들어갔다는 것을 기록
      5. ACK 번호를 서버측에 반송
      6. 애플리케이션이 데이터를 가지러 올 때까지 기다림.
      7. 애플리케이션이 read를 호출하면 데이터를 건네지 않고 서버에서 보낸 데이터를 전부 수신 완료했다는 사실을 클라이언트측의 애플리케이션에게 알림.
      8. 클라이언트측의 애플리케이션이 close를 호출하여 데이터 송, 수신 동작을 끝냄.
      9. 클라이언트측 프로토콜 스택은 FIN 비트에 1 설정한 TCP 헤더 만들고 IP 담당 부분에 의뢰하여 서버에 송신함.
      10. 서버에서 ACK 번호가 돌아오면 서버와의 대화 종료.

  1. 소켓을 말소한다.

    • 소켓을 바로 말소하지 않고 기다리는 이유

      • 클라이언트가 먼저 FIN을 송신했을 때 마지막에 서버가 FIN을 송신하고 클라이언트가 ACK 번호를 송신하게 된다.
      • 이 때 서버측에서 클라이언트에서 보낸 ACK 번호가 오지 않았다고 생각하여 FIN을 다시 보낼 때가 있다.
      • 만약 바로 클라이언트측에서 소켓을 말소했을 경우 기존 소켓의 포트 번호가 새 소켓에 할당될 수도 있기에 FIN 비트가 새 소켓으로 향하게 되어 연결 끊기 동작에 들어가는 경우가 발생.

  1. 데이터 송, 수신 동작을 정리한다

    KakaoTalk_20210930_223154192

    1. 소켓 작성 단계

      • 보통 서버측에서 소켓을 만들고 접속 대기 상태로 만든다.
      • 클라이언트측은 사용자가 조치를 취하여 서버에 액세스하는 동작이 시작될 때 패킷을 작성하지만 이 단계에서는 패킷을 주고받지 않는다.
    2. 접속 동작

      1. 클라이언트가 SYN이 1인 TCP 헤더를 만들어 서버에 보낸다.

        • 시퀀스 번호 초기값과 윈도우 값도 기록되어 있음
      2. 서버에서 SYN 1인 TCP 헤더가 돌아온다.

        • 시퀀스 번호 초기값과 윈도우 값, ACK 번호가 기록되어 있음
      3. 클라이언트에서 ACK 번호를 보낸다.
    3. 데이터 송, 수신 동작

      1. 클라이언트에서 리퀘스트 메시지가 분할된 데이터와 시퀀스 번호를 보낸다.
      2. 서버에 ACK 번호를 보낸다.

        • 최초가 아닌 진행 중일때는 윈도우 값도 기록하여 보낸다.
      3. 리퀘스트 메시지를 다 보내면 서버가 응답 메시지를 반송한다.

        • 위 설명과 반대로 진행됨
    4. 연결 끊기 동작

      1. 웹의 경우 서버에서 연결 끊기 동작에 들어감.
      2. 서버에서 FIN을 1로 만든 TCP 헤더 보냄
      3. 클라이언트에서 ACK 번호를 보냄
      4. 클라이언트에서 FIN을 1로 만든 TCP 헤더를 보냄
      5. 서버에서 ACK 번호를 보내고 잠시 후 소켓이 말소.

05 IP와 이더넷의 패킷 송, 수신 동작

  1. 패킷의 기본

    • 패킷은 '헤더'와 '데이터'의 두 부분으로 구성

      • 헤더에는 수신처를 나타내는 주소 등의 제어 정보가 들어있음
      • 그 뒤에 의뢰처에서 의뢰한 데이터가 있음
    • 패킷의 송신처 기기가 패킷을 만들고 헤더와 데이터를 넣은 후 가까운 중계 장치에 송신함.
    • 중계 장치가 패킷을 표를 이용해 분석하고 (중계 장치 안에는 어느 수신처가 있는지가 기록된 표와 같은 것이 있음) 이 내용을 결합하여 목적지에 송신하면 다음 중계 장치에 도착함
    • 이것이 반복되어 최종적으로 수신처에 패킷이 도착함.
    • 송신처가 수신처가 될 수 있기에 명확하게 구별하지 않고 하나로 묶어서 '엔드노드'라고 부름
    • 허브는 이더넷의 규칙에 따라 패킷을 운반, 라우터는 IP 규칙에 따라 운반.

      • 라우터 - IP 목적지를 확인하여 다음 IP 중계 장치를 나타낸다.
      • 허브 - 서브넷 안에 있는 이더넷이 중계 장치까지 패킷을 운반한다.
    • TCP/IP 패킷에는 두 개의 헤더가 붙어있다.

      • MAC 헤더(이더넷용 헤더)
      • IP 헤더(IP용 헤더)
    • 다음과 같이 역할을 분담하여 패킷을 운반

      1. 송신처에서 액세스 대상 서버 IP 주소를 IP 헤더의 수신처에 기록
      2. IP는 수신처가 어느 방향에 있는지 조사하고, 그 방향에 있는 다음 라우터를 조사.
      3. 이 라우터에 패킷이 도착하도록 이더넷에 의뢰하는데 이때 다음 라우터에 할당된 이더넷의 주소(MAC 주소)를 조사하고, 그것을 MAC 헤더에 기록함. 이렇게 해서 이더넷에게 어느 라우터에 패킷을 도착하면 좋은지를 전달함.
      4. 패킷을 송신하면 이더넷의 원리에 따라 움직이는 허브에 도착함.

        • 허브에는 패킷의 목적지를 판단하기 위한 표(이더넷용 표)가 있어 패킷의 목적지를 판단하여 중계함
        • 허브가 복수면 순차적으로 경유하여 패킷이 진행됨.
      5. 패킷은 다음 라우터에 도착함.

        • 라우터에는 IP용 표가 있어서 어느 라우터에 패킷을 중계하면 좋을지가 결정됨.
        • 다음 라우터에게 패킷을 건네주기 위해 라우터의 MAC 주소를 조사하고 MAC 헤더에 기록함.
      6. MAC 헤더를 바꾸어 쓰고 패킷을 다음 라우터에 송신함.
      7. 다시 또 허브를 경유하여 R2에 패킷이 도착. 이것을 반복하면 패킷은 목적지에 도착.
    • 이렇게 복잡하게 역할을 분담한 이유가 있다.

      • 이더넷 부분은 무선 LAN, ADSL, FTTH 등 다른 것으로 대체할 수 있다. IP와 조합하여 역할을 분담해서 통신 기술을 적재적소에 구분하여 사용할 수 있기에 이더넷과 같은 거대한 네트워크를 구축하려면 이와 같은 유연성이 꼭 필요하다.

  1. 패킷 송, 수신 동작의 개요

    1. TCP 담당 부분이 IP 담당 부분에 패킷 송신을 의뢰함.

      • 데이터의 조각에 TCP 헤더를 부가한 것을 건네줌. (이것이 패킷에 들어가는 내용물이며 통신 상대의 IP 주소를 나타냄)
    2. IP 담당 부분은 IP 헤더와 MAC 헤더를 부가함.

      • IP 헤더 - IP용 헤더, IP 주소를 씀
      • MAC 헤더 - 이더넷용 헤더, MAC 주소를 씀
    3. 만든 패킷을 네트워크용 하드웨어(이더넷, 무선 LAN 등)에 건네줌

      • 통칭 LAN 어댑터
      • 이 때 패킷의 모습은 0, 1 비트가 이어진 디지털 데이터.
      • LAN 어댑터에 의해 전기나 빛의 신호 상태로 바뀌 케이블에 송출됨.
    4. 신호는 허브나 라우터 등의 중계 장치에 도착하고, 중계 장치가 상대가 있는 곳까지 패킷을 전달함.
    5. 상대에게 패킷이 도착하면 회답이 돌아온다.

      • 송신 동작의 반대라고 생각.
      • 케이블에서 신호의 모습을 한 패킷이 들어오면 LAN 어댑터에서 디지털 데이터로 바꿔주고 이를 IP 담당 부분에게 건네줌. IP 담당 부분이 MAC 헤더와 IP 헤더 뒤의 내용물을 TCP 담당 부분에게 건네줌
    6. IP 패킷 송, 수신 동작은 패킷의 역할에 관계없이 모두 같다. 내용을 보지 않고 TCP 동작 단계도 신경쓰지 않는다. 그저 의뢰받은 내용물을 패킷의 모습으로 만들어 상대에게 송신하거나 전달한 패킷을 수신할 뿐이다.

  1. 수신처 IP 주소를 기록한 IP 헤더를 만든다.

    • IP 담당 부분은 TCP 담당 부분에서 패킷 송, 수신 의뢰를 받으면 IP 헤더를 만들어 TCP 헤더의 앞에 붙인다.

      • 가장 중요한 것은 수신처 IP 주소

        • IP 주소가 잘못되어도 상관없다. 판단하지 않고 그대로 헤더를 설정한다. 잘못되면 애플리케이션측에 책임이 있는 것으로 간주한다.
      • 송신처 주소도 설정함

        • IP 주소는 사실 컴퓨터에 할당되는 것이 아니라 LAN 어댑터에 할당 되는 것.
        • 여러 개의 LAN 어댑터를 장착하면 각 LAN 어댑터에 서로 다른 IP 주소가 할당됨.
        • 여러 개 IP 중 어느 IP 주소를 설정해야할지 판단하는 것 == LAN 어댑터 중 어느 LAN 어댑터를 사용하여 패킷을 송신해야 하는지를 판단하는 것 == 패킷을 건네주는 상대의 라우터를 결정하는 것
    • 패킷을 건네줄 상대를 판단하는 방법은 라우터가 IP용 표(경로표)를 사용하여 다음 라우터를 결정하는 동작과 같음.

      • 소켓에 기록된 수신처 IP 주소를 경로표의 왼쪽 끝에 있는 Network Destination 항목과 비교하여 어느 행에 해당하는지 찾아냄 (IP 주소의 왼쪽 부분이 일치하는 것을 찾아낸다)
      • Interface 항목과 Gateway 항목을 조사한다.

        • Interface 항목은 LAN 어댑터 등의 네트워크용 인터페이스를 나타냄. 인터페이스에서 패킷을 송신하면 상대에게 패킷을 전해줄 수 있다는 의미
        • Gateway 항목은 다음 라우터의 IP 주소를 기록하게 되어 있어서 IP 주소를 가진 라우터에 패킷을 건네주면 라우터가 목적지에 패킷을 중계해 준다는 것을 나타냄.
      • 맨 위 행에는 목적지와 넷마스크가 0.0.0.0으로 등록되어 있음. 이것은 소위 기본 게이트웨이를 나타내며, 일치하는 것이 없으면 이 행이 해당하는 것으로 간주.
      • 이렇게 해서 어느 LAN 어댑터에 패킷을 송신해야 하는지 알고 나서 LAN 어댑터에 할당되어 있는 IP 주소를 IP 헤더의 송신처 IP 주소로 설정함
    • 프로토콜 번호라는 필드에도 패킷에 들어간 내용물이 어디에서 의뢰받은 것인지를 나타내는 값을 설정함.

      • TCP는 06, UDP는 17. 값은 규칙에 결정되어 있음

  1. 이더넷용 MAC 헤더를 만든다.

    • 이더넷은 TCP/IP 개념이 통용되지 않는다.

      • TCP/IP와 다른 구조로 패킷의 수신처를 판단하며, 이 구조를 따르지 않으면 이더넷 패킷을 운반할 수 없다.
      • 이더넷의 수신처 판단 구조로 사용하는 것이 MAC 헤더
    • MAC 헤더의 맨 앞에는 수신처 MAC 주소와 송신처 MAC 주소가 있다.

      • 각각 패킷을 전달하는 상대와 송신한 송신처의 MAC 주소를 나타냄.
      • IP 주소와 달리 그룹화 개념이 없고 48비트를 한 개의 값으로 생각함.
    • 3개의 이더 타입(EtherType)이라는 항목은 IP 헤더의 프로토콜과 비슷함.

      • 이더 타입까지가 MAC 헤더고 그 뒤로 이어지는 것이 패킷의 내용물로 생각함.
    • 송신처 MAC 주소는 자체의 LAN 어댑터의 MAC 주소를 설정함.

      • 어댑터 제조할 때 ROM에 기록되어 있는 값
      • 송신처 IP 주소를 설정할 때 어느 LAN 어댑터에서 송신할지를 판단하고 나서 LAN 어댑터에 할당된 MAC 주소를 설정함.
    • 수신처 MAC 주소는 다소 복잡함.

      • 패킷을 건네주는 상대의 MAC 주소를 기록해야함.
      • 패킷을 건네줄 상대는 경로표에 기록되어 있음 (Gateway 항목)
      • 다만 이것은 IP 주소이기에 MAC 주소를 조사하는 동작을 실행함.

  1. ARP로 수신처 라우터의 MAC 주소를 조사한다.

    • 이더넷에는 연결되어 있는 전원에게 패킷을 전달하는 브로드캐스트라는 구조가 있는데 이를 이용해 IP 주소를 가지고 있으면 MAC 주소를 달라는 요청을 하고 해당하면 응답을 보내준다.

      • 상대가 자신과 같은 네트워크에 존재하면 이것으로 MAC 주소를 알 수 있다.
    • ARP 캐시라는 메모리 영역에 조사한 결과를 보존하여 다시 이용한다.

      • ARP 캐시의 내용과 현실 사이에 일치하지 않을 수 있기에 시간이 되면 삭제하게 되어 있음
    • MAC 헤더를 IP 헤더 앞에 붙이면 패킷이 완성되는데 이까지가 IP 담당 부분의 역할.

      • IP 이외의 특수한 패킷도 한 개의 LAN 어댑터로 대응할 수 있다.

  1. 이더넷의 기본

    • 이더넷은 다수의 컴퓨터가 여러 상대와 자유롭게 적은 비용으로 통신하기 위해 고안된 통신 기술

      KakaoTalk_20211001_003010059

    • 이더넷의 원형

      • 네트워크의 실체는 케이블만 있음.
      • 컴퓨터가 신호를 송신하면 케이블을 통해 네트워크 전체에 신호가 흐르고 전원에게 신호가 도착함.
      • 이 동작만으로는 도착한 신호가 누구에게 갈 것인지 판단할 수 없어 신호의 맨 앞부분에 수신처 주소를 써둔다.
    • 리피터 허브를 이용한 파생형

      • 모습은 바뀌었지만 신호가 전원에게 전달한다는 기본적인 성질은 변하지 않았다.
    • 스위칭 허브를 이용한 형태

      • 현재는 이더넷이라 말하면 이 형태를 가리킴.
      • 전원에게 전달되는 것이 아닌 수신처 MAC 주소로 나타내는 원하는 기기가 존재하는 부분에만 신호가 흐름.
      • 수신처 MAC 주소의 상대에게 패킷이 전달되는 점은 변하지 않았으므로 MAC 헤더의 개념은 그대로임.
    • MAC 헤더의 수신처 MAC 주소에 기억된 상대에게 패킷을 전달하고, 송신처 MAC 주소로 송신처를 나타낸 후 이더 타입으로 패킷의 내용물을 나타낸다는 세 가지 성질은 지금도 변하지 않았고 이 세 가지 성질을 가진 것이 이더넷이라고 생각하자.
    • 이더넷도 IP와 마찬가지로 패킷의 내용물을 보지 않으므로 송, 수신 동작은 TCP 동작 단계에 상관없이 모든 것이 공통.

  1. 서버의 응답 패킷을 IP에서 TCP로 넘긴다.

    • 서버에서 반송된 패킷의 타입이 0800이면 패킷의 내용이 IP 프로토콜의 데이터라는 뜻이므로 LAN 드라이버는 TCP/IP의 프로토콜 스택에 패킷을 건넬 것이다.
    • IP 담당 부분은 헤더 부분부터 조사하여 문제가 없는지 확인하고 수신처 IP 주소를 조사한다.
    • 만약 수신처 IP 주소가 자신의 주소와 다르면 ICMP라는 메시지를 사용하여 통신 상대에게 오류를 통지하게 되어 있다.
    • 수신처 IP 주소가 올바르면 이것을 수신하지만, 한 가지 할 일이 더 있다.

      • IP 프로토콜에는 조각 나누기(fragmentation)라는 기능이 있다.

        • 패킷을 짧게 하기 위해 하나의 패킷을 여러 개로 분할하는 것.
      • 수신한 패킷이 분할된 것이면 IP 담당 부분은 그것을 원래 패킷으로 되돌린다.

        • 분할된 패킷은 IP 헤더에 플래그라는 항목을 보면 알 수 있는데 분할된 것이면 IP 담당 부분 내부의 메모리에 일시적으로 보관한다.
        • IP 헤더에 ID 정보에 같은 값을 가진 패킷이 도착하기를 기다린다. 분할된 패킷은 모두 같은 값.
        • 프래그먼트 오프셋이라는 항목에는 패킷이 원래 패킷의 어느 위치에 있었는지를 나타내는 정보가 있다.
        • 이 정보들을 바탕으로 분할된 패킷이 전부 도착하면 원래의 모습으로 되돌리는 동작인 리어셈블링을 한다.
      • 리어셈블링이 끝나면 패킷을 TCP 담당 부분에 건네준다.
      • IP 헤더에 기록된 수신처 IP 주소와 송신처 IP 주소, TCP 헤더에 기록된 수신처 포트 번호 및 송신처 포트 번호의 네 가지 항목을 조사하여 해당하는 소켓을 찾는다.
      • 해당하는 소켓을 찾아내면 상황에 따라 적절한 동작을 실행
    • TCP 담당 부분에서 IP 헤더를 이용해 소켓을 찾는게 어색할 수도 있으나 만약 IP 담당 부분에서 IP 헤더를 처리해서 TCP 담당 부분으로 IP 주소를 넘기는 방식이면 프로그램의 실행 효율이 저하됨. 그러므로 이런 방식으로 진행한다.

06 UDP 프로토콜을 이용한 송, 수신 동작

  1. 수정 송신이 필요없는 데이터의 송신은 UDP가 효율적이다.

    • DNS 서버에 IP 주소를 조회할 때도 UDP 프로토콜을 사용한다.
    • TCP가 복잡한 원리를 사용할 이유는 데이터를 확실하면서도 효율적으로 전달하기 위해서이다.
    • 데이터를 보낸 후 오류로 다시 보낼 때 효율적으로 보내기 위해서는 도착한 패킷은 다시 보내지 않고 오류로 도착하지 않은 패킷만 다시 보내는 구조가 필요하다. TCP가 이 일을 한다.
    • TCP의 복잡한 구조를 사용하지 않으면 제어용 패킷을 보낼 필요가 없음. 수신 확인 응답 패킷도 필요없다.

  1. 제어용 짧은 데이터

    • DNS 서버에 대한 조회 등 제어용으로 실행하는 정보 교환은 한 개의 패킷으로 끝나는 경우가 많으므로 TCP가 아닌 UDP를 사용한다.
    • UDP에는 TCP와 같은 수신 확인이나 윈도우가 없어서 송, 수신 전에 제어 정보를 주고받을 필요가 없고, 접속이나 연결 끊기 단계가 없다.
    • 애플리케이션에서 송신 데이터를 받으면 UDP 헤더를 부가하고 이것을 IP에 의뢰하여 송신하기만 한다.
    • 수신도 IP 헤더의 수신처 IP 주소, 송신처 IP 주소, UDP 헤더의 수신처 포트 번호, 송신처 포트 번호라는 네 항목과 소켓에 기록된 정보를 결합하여 데이터를 건네주기만 하면 된다.
    • 오류가 발생하여 패킷이 없어져도 모른 체한다.

      • 오류가 발생하면 회답이 돌아오지 않으므로 데이터를 한 번 더 다시 보내면 그만이다.
      • 복잡한 동작이 필요하지 않아 애플리케이션의 부담이 커지지도 않는다.

  1. 음성 및 동영상 데이터

    • 음성이나 영상의 데이터를 보낼 때도 UDP를 사용한다.
    • TCP와 같이 수신 확인 응답에 의해 오류를 검출하여 다시 보내는 방법이라면 시간이 걸리고 다시 보내도 재생 타이밍이 맞지 않을 수 있다.
    • 다시 보낼 필요가 없거나 다시 보내도 쓸모가 없으면 단순히 UDP로 데이터를 보내는 쪽이 더 효율적이다.

다음 장에서는 케이블에서 나간 패킷이 리피터 허브, 스위칭 허브, 라우터라는 기기를 경유하여 인터넷으로 나가는 부분까지 탐험한다.