합동회사 코무라소프트
1장

도입 — TCP 는 무엇을 약속하는가

IP 만의 세계에서는 도착하지 않고·흐트러지고·중복된다는 전제에서 출발하여, TCP 의 3 가지 약속과 UDP 와의 분담, 포트 번호와 소켓의 역할을 파악한다.

「타임아웃되었습니다」의 그 다음으로 나아가지 못한다

접속 타임아웃 로그는 찾았다. 리트라이했더니 고쳐졌다. 하지만 「왜」는 모른 채로 — TCP 의 장애 조사는 많은 사람이 여기서 멈춥니다. 패킷 캡처를 열어도 seqack, win 이라는 숫자의 나열이 무엇을 말하는지 읽지 못하기 때문입니다.

읽을 수 있게 되는 지름길은 TCP 의 기능을 암기하는 것이 아니라, TCP 가 어떤 토대 위에서 무엇을 약속하려 하는가를 먼저 파악하는 것입니다. 출발점은 TCP 아래에 있는 IP 의 성질입니다. IP 는 패킷(데이터의 소포)을 목적지 호스트까지 운반하지만, 그 배달은 「베스트 에포트」 — 최선은 다하지만 결과는 보증하지 않는다는 약속입니다. 구체적으로는 경로 상에서 이렇게 됩니다.

도착하지 않을 수 있다
혼잡한 라우터는 넘친 패킷을 말없이 버린다. 버렸다는 사실은 누구에게도 통지되지 않는다
순서가 뒤바뀔 수 있다
패킷마다 지나는 경로가 다르면, 나중에 보낸 것이 먼저 도착한다
중복될 수 있다
재전송 구조와 배달 지연이 겹치면, 같은 패킷이 2 번 도착한다

이 토대 위에서 「파일을 1 바이트도 빠뜨리지 않고, 순서대로 전달하는」 일을 애플리케이션 대신 떠맡는 것이 TCP(Transmission Control Protocol)입니다.

잃어버리고·흐트러뜨리고·중복시키는 IP 위에 TCP 와 UDP 가 올라가고, TCP 가 반드시 도착한다·순서대로·페이스를 맞춘다는 3 가지 약속을 애플리케이션에 제공하는 계층 구조의 그림

IP 는 「아마 도착한다」까지. 그 위에서 TCP 는 3 가지 약속을 지키고, UDP 는 일부러 거의 그대로 통과시킵니다. 어느 쪽이 더 훌륭한 것이 아니라, 역할이 다릅니다.

TCP 의 3 가지 약속 — 이 강좌의 등뼈

TCP 의 구조는 언뜻 많아 보이지만, 모두 다음 3 가지 약속 중 어느 하나를 지키기 위한 도구입니다. 이 강좌에서는 매 장마다, 지금 배우고 있는 구조가 어느 약속을 위한 것인지로 되돌아갑니다.

약속의미실현하는 도구다루는 장
반드시 도착한다 — 도착하지 않으면 알아챈다빠지면 감지하여 재전송한다시퀀스 번호 + ACK + 재전송 타이머제 2〜3 장
순서대로흐트러짐·중복을 바로잡은 뒤에 건넨다시퀀스 번호 + 수신 버퍼제 3 장·제 6 장
상대와 네트워크에 맞춘다받는 쪽과 경로의 사정보다 빠르게 보내지 않는다윈도우(흐름 제어) + cwnd(혼잡 제어)제 4〜5 장

한편 UDP(User Datagram Protocol)는 이 약속을 일부러 아무것도 하지 않습니다. IP 의 베스트 에포트에 「포트 번호」와 최소한의 체크만을 더한 얇은 층입니다. 대충 만든 것이 아니라, 재전송이나 순서 대기가 방해가 되는 용도(화상 통화, 온라인 게임, DNS 질의 등)를 위한 선택지입니다. TCP 의 3 가지 약속에는 지연이라는 비용이 반드시 따라오기 때문입니다.

소문제 1-1 — IP 의 성질과 TCP/UDP 의 분담

「IP 는 무엇을 해 주지 않는가」를 정확히 말할 수 있는 것이 TCP 를 이해하는 출발점입니다.

Q1. IP 만으로(TCP 없이) 데이터를 보냈을 때, 경로 상에서 흔히 일어날 수 있는 일로 올바른 조합은 어느 것입니까.

Q2. TCP 가 아니라 UDP 를 선택하는 것이 적절한 상황은 어느 것입니까.

Q3. TCP 가 약속하지 않는 것은 어느 것입니까.

포트 번호와 소켓 — 대화의 입구를 특정한다

IP 주소는 「어느 호스트인가」를 가리키지만, 도착한 곳의 호스트에서는 웹 서버도 데이터베이스도 SSH 도 동시에 돌고 있습니다. 그 호스트의 어느 프로그램 앞인가를 가리키는 또 하나의 번호가 포트 번호입니다(0〜65535. HTTPS 는 443, SSH 는 22 등).

그리고 IP 주소 : 포트 번호 의 조합이 가리키는 통신의 입구를 소켓이라고 부릅니다. 프로그램에서 보면 소켓은 「상대와 이어진 바이트의 파이프」로, send() 로 흘려 넣고 recv() 로 받습니다(이 파이프의 의외의 성질이 제 6 장의 주역입니다).

여기서 중요한 것은, TCP 커넥션 1 개를 식별하는 것이 목적지만이 아니라는 점입니다. 커넥션은

(송신원 IP, 송신원 포트, 목적지 IP, 목적지 포트)

라는 4 요소 조합으로 식별됩니다. 그래서 1 대의 서버 포트 443 에 수만 개의 클라이언트가 동시에 접속할 수 있습니다 — 목적지 측은 같아도, 송신원 측의 IP 나 포트(클라이언트 측은 비어 있는 번호가 자동으로 할당됩니다)가 다르면 다른 커넥션이기 때문입니다.

이 강좌의 표어: 캡처나 장애 로그를 보면 물어보세요 — 지금 깨지려 하는 것은, 도달의 약속인가? 순서인가? 페이스 맞추기인가?

소문제 1-2 — 포트 번호와 소켓

IP 주소만으로는 부족한 「또 하나의 번호」의 역할을 확인합니다.

Q4. IP 주소에 더해 포트 번호가 필요한 이유로 올바른 것은 어느 것입니까.

Q5. 1 대의 서버 포트 443 에 다수의 클라이언트가 동시에 접속할 수 있습니다. 서버가 개별 커넥션을 헷갈리지 않고 구별할 수 있는 이유는 무엇입니까.

이 장에서 가져갈 것

  • IP 는 베스트 에포트 — 잃어버리고·흐트러뜨리고·중복시킨다. 게다가 그것을 통지하지 않는다
  • TCP 의 약속은 3 가지 — 반드시 도착한다(도착하지 않으면 알아챈다)·순서대로·상대와 네트워크에 맞춘다. 시간의 보증은 없다
  • UDP 는 약속 대신 저지연을 취하는 선택지. 용도에 따라 구분해 사용한다
  • 커넥션은 (송신원 IP, 송신원 포트, 목적지 IP, 목적지 포트) 의 4 요소 조합으로 식별된다

다음 장에서는 이 4 요소 조합의 양 끝이 「이제부터 번호를 세기 시작할게」라고 합의하는 의식 — 3 웨이 핸드셰이크 — 를 1 패킷씩 따라갑니다.