개요

이 장에서는 OS에 내장된 네트워크 제어용 소프트웨어인 프로토콜 스택과 네트워크 하드웨어인 LAN 어댑터가 브라우저에서 받은 메시지를 서버에 송출하는 것을 알아본다.

  1. 소켓을 작성한다
  2. 서버에 접속한다
  3. 데이터를 송/수신한다
  4. 서버에서 연결을 끊어 소켓을 말소한다.
  5. IP와 이더넷의 패킷 송/수신 동작
  6. UDP 프로토콜을 이용한 송/수신 동작

1. 소켓을 작성한다

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

TCP/UDP

  • TCP - 브라우저나 메일 등의 일반적인 애플리케이션이 데이터를 송수신 하는 경우
  • UDP - DNS 서버에 대한 조회 등에서 짧은 제어용 데이터를 송수신 하는 경우

IP

  • 패킷의 송수신동작 제어
  • ICMP - 패킷을 운반할 때 발생하는 오류 통지, 제어용 메시지 통지
  • ARP - IP주소에 대응하는 이더넷의 MAC 주소를 조사

LAN 드라이버/어댑터

  • LAN 어댑터의 하드웨어를 제어하고 LAN 어댑터가 실제 송수신동작(케이블로 신호를 송신하는) 역할을 담당

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

소켓은 개념적인 것이어서 실체가 없다. 프로토콜 스택 내부에 제어정보를 기록한 메모리 영역 혹은 그 제어정보 자체가 소켓이라고 생각하자

  • 프로토콜 스택은 소켓에 기록된 제어정보를 참조하면서 움직인다
  • 제어정보는 PID, IP주소와 포트번호(나, 상대), 통신상태, 프로토콜의 종류 등에 대한 정보를 가짐

3. Socket을 호출했을 때의 동작

브라우저가 socket이나 connect라는 소켓 라이브러리의 프로그램 부품을 호출했을때 어떤 작업이 진행될까?

애플리케이션이 socket() 호출하면 프로토콜 스택은 의뢰에 따라 한개의 소켓을 만듬

  • 소켓 한개 분량의 메모리 영역을 확보하고 초기 상태라는 것을 기록해놓음
  • 소켓이 만들어 지면 디스크립터를 애플리케이션에 알려줌
    • 이후 데이터의 송 수신 동작의 의뢰 때마다 이 디스크립터를 통지하여 어떤 소켓인지 특정할 수 있음

2. 서버에 접속한다 (≒ 준비한다)

1. 접속의 의미

소켓을 만들면 애플리케이션은 connect()를 호출한다. 프로토콜 스택은 내쪽의 소켓을 서버측 소켓에 접속한다.

  • 통신 상대와 제어정보를 주고받아 필요한 정보를 기록하고 데이터 송수신이 가능한 상태로 만든다
  • 송수신하는 데이터를 일시적으로 저장하는 메모리 영역이 필요한데, 이 메모리 영역을 버퍼메모리라고 부르며 이 메모리의 확보도 접속동작을 할때 이루어진다.

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

제어정보는 크게 2가지로 나눌 수 있다.

  • 헤더에 기입되는 정보 : TCP 프로토콜의 사양으로 규정하고 있음
  • 소켓(프로토콜 스택의 메모리 영역)에 저장되는 정보
    • 애플리케이션에서 통지된 정보, 통신상대로부터 받은 정보, 진행상황들이 수시로 기록됨 ← 프로토콜 스택이 작업할 때 필요로 하는 정보

3. 접속 동작의 실제

  1. 애플리케이션이 소켓 라이브러리의 connect를 호출 - connect(<디스크립터>, <서버측의 IP 주소와 포트번호>, …)
  2. 데이터 송수신 동작의 개시를 나타내는 제어 정보를 기록한 TCP 헤더를 만든다
    • 송신처와 수신처의 포트 번호
    • 컨트롤 비트인 SYN의 비트를 1로 만듬
  3. TCP 헤더의 송신처와 수신처 포트 번호로 접속할 소켓을 지정한다
  4. IP 담당 부분에 건네주어 송신하도록 의뢰한다.
  5. IP 담당 부분이 패킷 송신 동작을 실행하고 패킷이 서버에 도착하면 서버측의 IP담당이 서버의 TCP로 건네준다.
  6. 서버측의 TCP 담당 부분이 TCP 헤더를 조사해 수신처 포트 번호에 해당하는 소켓을 찾아내고(접속을 기다리는 상태에 있는 소켓 중에서 TCP헤더의 수신처 포트 번호와 같은 번호가 기록된 소켓), 필요한 정보를 기록하고 접속 동작이 진행중이라는 상태가 됨
  7. 서버의 TCP담당은 클라이언트에게 응답을 돌려보냄(SYN 1), ACK 컨트롤 비트를 1로 만들어 돌려보냄.(패킷을 받은것을 알리기 위해서)
  8. 다시 패킷이 클라이언트에 돌아오면 TCP 헤더를 조사해 서버측의 접속 동작이 성공했는지를 확인한다. SYN이 1이면 성공이므로 클라이언트 측 소켓에 서버의 IP주소, 포트번호 그리고 접속 완료를 나타내는 제어정보를 기록
  9. 패킷이 도착한 것을 서버에 알리기 위해 ACK 비트를 1로 만든 TCP 헤더를 반송
  10. 서버에 도착하면 “접속 동작”의 대화가 완료됨

→ 위의 과정을 통해서 소켓은 데이터를 송수신 할 수 있는 상태가 된다.(마치 양 소켓이 파이프와 같은 것으로 연결 되었다고 생각하자) 이러한 파이프를 Connection이라고 부른다. 이 커넥션은 close를 호출해서 연결을 끊을 때 까지 계속 존재한다.

3. 데이터를 송/수신 한다

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

connect 함수를 호출하고, 접속 동작이 완료되면 애플리케이션에 제어가 되돌아가고 데이터 송수신 동작에 들어간다. 이 동작은 애플리케이션이 write()를 호출하여 송신 데이터를 프로토콜 스택에 건네주면 프로토콜 스택이 송신 동작을 실행한다.

  • 프로토콜 스택은 받은 데이터의 내용이 무엇인지 알지 못하고, write를 호출할때 송신 데이터의 길이를 명시한 만큼 바이너리 데이터가 1바이트씩 차례로 나열되어있다고 인식한다.
  • 받은 데이터를 곧바로 송신하는 것이 아니고 송신용 버퍼 메모리 영역에 저장
    • 데이터의 길이는 애플리케이션의 종류나 만드는 방법에 따라 달라질 수 있음(한번에 전부 의뢰하거나, 1바이트 혹은 1행 씩 세분하거나)
  • 어느정도까지 저장후 송신할지는 아래 두가지 기준이 있으며, 전자를 중시하면 패킷의 길이가 길어져 네트워크의 이용 효율이 높아지지만, 버퍼에 머무는 시간만큼 송신 동작이 지연될 수 있는 트레이드 오프 관계이다.
    1. MTU 및 MSS라는 매개변수를 바탕으로 판단한다. MSS에 가까운 길이에 이르기까지 데이터를 저장하고 송신동작을 한다.
    2. 타이머: 버퍼에 데이터가 충분히 모이지 않아도 적당한 곳에서 송신동작을 실행하기 위해서 일정 시간 이상 경과하면 패킷을 송신한다.
  • 애플리케이션에서 송신의 타이밍을 제어 할 수도 있다.(즉시 송신하라고 지정)

MTU : 패킷 한 개로 운반할 수 있는 디지털 데이터의 최대 길이. 이더넷에서는 보통 1,500byte

MSS: 헤더를 제외하고 한 개의 패킷으로 운반할 수 있는 TCP 데이터의 최대 길이

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

HTTP 리퀘스트 메시지는 보통 한개의 패킷에 들어가지만, 폼을 사용해 긴 데이터를 보낼 경우엔 한개의 패킷으로는 처리가 불가능하다. 이 경우 송신 버퍼에 저장된 데이터는 MSS 길이를 초과하므로 송신 버퍼에 들어있는 데이터를 맨 앞부터 차례대로 MSS 크기에 맞게 분할하고, 분할한 조각을 한 개씩 패킷에 넣어 송신한다.

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

TCP는 송신한 패킷이 올바르게 도착했는지 확인하고, 도착하지 않았으면 다시 송신하는 기능이 있으므로 패킷을 송신한 후에 확인동작으로 넘어간다.

  • 데이터를 조각으로 분할 할 때 통신 개시부터 따져서 몇번째 바이트에 해당하는지를 세어두고, TCP 헤더를 붙일 때 시퀀스 번호라는 항목에 기록한다.
  • 수신측에서 패킷 전체의 길이에서 헤더 길이를 빼 데이터의 길이를 계산한다. ACK 번호를 반환할때 데이터 길이 + 1로 반환한다.
  • → 위 2가지를 조합하여 송신한 데이터가 몇 번째 byte부터 시작되는 몇byte 분의 것인지 알아낼 수 있다

이러한 방식으로 수신측에서 패킷 누락여부 확인 가능. 이러한 ACK 번호를 되돌려 주는 동작을 수신 확인 응답이라고 부른다.

실제 시퀀스 번호는 1부터 시작하지 않고 난수를 바탕으로 산출한 초기값으로 시작한다.(접속 동작 부분에서 SYN 제어비트를 1로 설정하면서, 시퀀스 난수 초기값도 같이 통지한다.)

3Way handshake

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

  1. 클라이언트에서 서버로 보내는 데이터에 관한 시퀀스 번호의 초기값을 클라이언트에서 산출하여 서버에 통지한다.(SYN)
  2. 초기값으로부터 ACK 번호를 산출하여 클라이언트에 반송
    1. 이때 서버에서 클라이언트에 보내는 데이터에 관한 시퀀스 번호의 초기값도 같이 클라이언트에 통지한다.(SYN)
  3. 클라이언트도 시퀀스 번호의 초기값으로부터 ACK 번호를 산출하여 서버에 반송

TCP는 송신한 패킷을 송신용 버퍼 메모리 영역에 보관해 두다가 그 패킷에 대응하는 ACK 번호가 되돌아 오지 않으면 패킷을 다시 보낸다.

도착하지 않으면 다시 보내므로, 네트워크 어디에서 오류가 발생하더라도 전부 검출해서 회복 처리를 취할 수 있다. LAN 어댑터, 버퍼, 라우터 모두 회복조치에는 관여하지 않는다.

다만, 케이블이 분리되거나 서버가 다운되는 사유로 아무리 다시 보내도 소용없는 경우는 몇번 보내보고 데이터 송신을 중단하고 애플리케이션에 오류를 통지한다.

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

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

네트워크의 혼잡 등을 이유로 ACK가 돌아오는 것이 지연될 수도 있으므로 이것을 예측하여 대기시간을 어느정도 길게 설정해야 한다. 그렇지 않으면 무의미하게 ACK번호가 돌아오기 전에 같은 패킷을 여러번 보낼 수 있기 때문. 대기시간은 짧지도 길지도 않은 적절한 값으로 설정되어야 하는데, 영향을 미치는 환경 변수가 많으므로(서버의 거리, 정체 등) 대기 시간을 일정한 방법으로 설정하는 것이 적절하지 않다.

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

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

ACK 번호가 돌아올 때 까지 마냥 기다리는 것은 비효율적이기 때문에(이러한 방식은 핑퐁방식이라고 칭함), TCP는 윈도우 제어라는 방식에 따라 송신과 ACK 번호 통지의 동작을 실행한다.

윈도우 제어 방식

  • 수신측의 TCP는 패킷을 수신하면 일단 버퍼 메모리에 데이터를 보관(ACK 번호를 계산하거나 패킷 조각을 연결해서 원래 데이터를 복원해야 하는데, 처리 과정이 끝나기도 전에 새로운 패킷이 도착할 수도 있기 때문에)
  • 수신 버퍼의 용량을 초과하는 패킷이 도착하면 데이터가 없어져 버린다.

→ 수신측에서 송신측에 수신 가능한 데이터의 양을 통지하고, 송신측은 이 한도에 맞게 송신동작을 실행하는것이 윈도우 제어 방식

  • 수신 버퍼에 빈 부분이 생기면 TCP 헤더의 윈도우 필드에서 이것을 송신측에 알린다.

수신 가능한 데이터 양의 최대값을 윈도우 사이즈라고 부른다(보통 수신측의 버퍼 메모리 크기)

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

통지 시점

  • 윈도우: 수신측에서 송신측으로 윈도우 통지를 해야하는 시점은, 수신버퍼에 있는 패킷을 처리 완료 해서 빈 영역이 생겼을 때이다. (데이터를 보낼때는 송신측에서 알아서 감산하여 계산하기 때문)
  • ACK 번호: 수신측에서 데이터를 받았을 때 정상 수신을 확인하면 즉시

문제점 : 시점이 다르기 때문에 두 종류의 패킷이 따로따로 보내지고 효율성이 저하됨

→ 이를 해소하기 위해 ACK 번호나 윈도우를 통지할 때 잠시 기다려 다음 통지 동작이 일어나면 양쪽을 같이 묶어서 보낸다(합승)

  • 복수의 ACK 번호 통지가 연속해서 일어난 경우에도 패킷의 수를 줄일 수 있다. ACK 번호는 데이터를 어디까지 받았는지, 즉 수신한 데이터의 끝이 어디인지를 송신측에 알리는 것이므로 ACK 번호 통지가 연속해서 일어나면 제일 마지막 것만 통지하고 앞의 것들은 생략해도 무방
  • 복수의 윈도우 통지가 연속해서 일어나는 경우도 마찬가지이다

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

이 과정은 6장에서 자세하게 다룬다

  1. read 프로그램을 호출하여 응답 메시지를 받는다.
  2. 데이터 조각과 TCP 헤더의 내용을 조사해서 누락 여부를 검사한다.
  3. 이상이 없으면 ACK 번호를 반송한다.
  4. 데이터 조각을 수신 버퍼에 임시적으로 보관한다
  5. 조각을 연결하여 원래 데이터를 만들고 애플리케이션이 지정한 메모리 영역에 기록하고 제어를 애플리케이션으로 넘긴다.
  6. 타이밍을 가늠하여 윈도우를 송신측에 통지한다.(이 때 ACK 합승이 가능하다면 합승한다.)

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

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

일반적으로 HTTP 리퀘스트를 보내고 서버가 응답을 보내면 서버측이 연결 끊기 단계에 들어감(HTTP 1.0 기준)

  1. 서버측이 소켓 라이브러리의 close()를 호출한다.
  2. 프로토콜 스택이 TCP 헤더를 만들고, 연결 끊기를 나타내는 정보를 설정한다.
    • 컨트롤 비트의 FIN 비트에 1을 설정
  3. IP 담당 부분에 송신 의뢰 및 서버의 소켓에 연결 끊기 동작에 들어갔다는 정보를 기록
  4. 클라이언트측의 프로토콜 스택은 FIN을 설정한 TCP 헤더가 도착하면, 자신의 소켓에 서버가 연결끊기 동작에 들어갔다는 것을 기록
  5. FIN 받은것을 확인해주기 위해 ACK 패킷 반송, 애플리케이션이 데이터를 가지러 올 때 까지 기다림
  6. 클라측의 애플리케이션이 read를 호출하여 데이터를 가지러 오는 동작을 취함
  7. 데이터를 건네지 않고(수신버퍼에 남아있는 데이터는 줄 수있음) 서버에서 보낸 데이터를 전부 수신완료 했다고 클라이언트의 애플리케이션에게 알림
  8. 클라이언트의 애플리케이션도 close()를 호출하여 데이터 송 수신 동작을 끝냄
  9. 클라이언트 측의 프로토콜 스택은 FIN 비트에 1을 설정한 TCP 헤더를 만들고 IP 부분에 의뢰하여 서버에 송신
  10. 서버는 ACK를 반송
  11. 클라이언트가 ACK를 확인하면 모든 과정 종료

2. 소켓을 말소한다

오동작을 막기 위해 즉시 말소하지 않고 잠시 기다린 후 말소한다.

  1. 클라이언트가 FIN 송신
  2. 서버가 ACK 번호 송신
  3. 서버가 FIN 송신
  4. 클라이언트가 ACK 번호 송신

위와 같은 방식으로 연결 종료가 진행되는데, 만약 클라이언트가 ACK 번호를 보낼때 문제가 생겨서 서버가 다시한번 FIN을 보내는 경우를 가정해보자.

이 때 클라이언트의 소켓이 말소되어 있으면, 기록 되어있는 제어정보가 없어지므로 소켓에 해당되어 있던 포트번호도 몇번인지 알 수 없게된다. 이 시점에서 새로운 소켓을 작성하고 그 소켓에 같은 포트번호가 할당된다면? FIN은 말소되기 이전의 소켓에 보낸 것이지만, 새 소켓에 FIN이 도착하여 연결을 끊어버리는 오동작이 생길 수도 있다.

  • 기다리는 시간: 일반적으로 몇분 정도 기다리고 나서 소켓을 말소한다.

3. 데이터 송수신 동작(정리)

최초엔 서버측에서 소켓을 만들고 접속 대기상태로 만들어 놓는다.

접속동작(3 - handshake)

  1. 클라이언트가 SYN을 1로 만든 TCP 헤더를 서버로 보낸다. 시퀀스 번호의 초기값과 윈도우의 값도 같이 보낸다.
  2. 서버에서 SYN을 1로 만든 TCP 헤더를 답신한다. 마찬가지로 시퀀스 번호의 초기값, 윈도우, 그리고 1번의 요청을 받았다는 것을 확인하는 ACK번호도 기록되어 있다.
  3. 클라이언트에서 ACK번호를 기록한 TCP 헤더를 답신하면 접속 동작이 완료된다.

송수신동작(웹의 경우)

클라이언트가 서버에 리퀘스트 메시지를 보내는 것부터 시작

  1. TCP는 이것을 적당한 크기의 조각으로 분할하고, TCP 헤더를 맨 앞에 부가하여 서버에 보냄. 송신데이터가 몇번째 바이트 부터 시작되는지를 나타내는 시퀀스 번호를 기록
  2. 서버에 도착하면 서버는 ACK 번호를 기록하여 반송(수신 버퍼에 빈 영역이 생기면 윈도우의 값도 같이 반송한다)

서버의 응답메시지도 마찬가지로 이루어짐

연결 끊기 동작(4 - handshake)

서버가 응답 메시지를 보내면, 데이터 송수신 동작이 끝나므로 연결 끊기 동작에 들어감

  1. 서버에서 FIN을 1로 만든 TCP 헤더를 보냄(웹의 경우 서버가 먼저 끊기 때문)
  2. 받았음을 나타내는 ACK번호를 회신함
  3. 클라이언트에서 FIN을 1로 만든 TCP 헤더를 보냄
  4. 서버에서 ACK 번호를 회신하면 모든 상태 종료.(소켓 말소 까지는 잠시 대기시간 있음)
  • 2, 3번을 같이 할 수 없는 이유: 연결 끊기 상태가 되었다는것을 인지하고 수신버퍼를 처리하는 시간이 필요하기 때문

5. IP와 이더넷의 패킷 송수신 동작

1. 패킷의 기본

패킷은 헤더와 데이터(페이로드) 두 부분으로 구성된다.

엔드노드 : 송신처, 수신처를 묶어서 통칭 / 중간 노드 : 중계 장치

  • 서브넷은 라우터와 허브 두 종류의 패킷 중계장치에서 역할을 분담하며 패킷을 운반한다
    • 라우터: 목적지를 확인하여 다음 라우터를 나타낸다.
      • → IP가 목적지를 확인하여 다음 IP의 중계장치를 나타낸다.
    • 허브: 허브가 서브넷 안에서 패킷을 운반하여 다음 라우터에 도착한다.
      • → 서브넷 안에 있는 이더넷이 중계 장치까지 패킷을 운반한다.
  1. 송신처에서 패킷의 목적지가 되는 액세스 대상 서버 S의 IP주소를 IP헤더의 수신처에 기록한다.
  2. IP는 이 수신처가 어느 방향이 있는지를 조사하고, 그 방향에 있는 다음 라우터를 조사한다.
  3. 다음 라우터에 패킷을 보내도록 이더넷에 의뢰한다.
  4. 라우터에 할당된 이더넷 주소(MAC 주소)를 조사하고, MAC 헤더에 기록한다(R1). 그리고 송신한다.
  5. 허브에 도착한다. 허브에는 패킷의 목적지를 판단하기 위한 이더넷용 표가 있어서 이더넷 헤더의 수신처 정보와 표를 대조해서 패킷의 목적지를 판단하고 중계한다.(허브가 복수이면, 허브를 순차적으로 경유하여 패킷이 나아간다)
  6. 패킷이 다음 라우터에 도착한다.(⓶) 라우터에는 IP용 표가 있으므로 이것과 IP 헤더의 수신처를 대조해서 어느 라우터에 패킷을 중계해야 할지 결정한다.
  7. 다음 라우터에 패킷을 건네주기 위해 라우터의 MAC 주소(R2)를 조사하고 MAC 헤더에 기록한다(MAC 헤더를 바꾸어 쓴다). 패킷을 다음 라우터에 송신한다.
  8. 허브를 경유하여 다음 라우터인 R2에 도착한다.
  9. 6-8의 과정이 반복되며 목적지에 도착한다.

이더넷 부분은 무선 LAN, ADSL, FTTH등 IP의 의뢰를 받아 패킷을 운반할 수 있는 것이면 무엇이든지 이더넷을 대신하여 사용 될 수 있음

2. 패킷 송수신 동작의 개요

프로토콜 스택의 IP담당 부분의 패킷 송신 동작에 대해서 알아본다.

IP 담당 부분은 패킷을 상대에게 송출만 하기 때문에 그 후에 패킷을 상대가 있는 곳까지 운반하는 역할은 허브나 라우터 같은 네트워크 기기의 역할이므로 전체 운반의 입구부분만을 담당한다.

과정

  1. TCP 담당 부분이 IP담당 부분에 패킷 송신을 의뢰
  2. IP 담당 부분은 이 패킷을 하나의 디지털 데이터로 간주하고, 그 앞에 제어 정보를 기록한 헤더를 부가(MAC, IP)

IP 담당 부분은 다음 두개의 헤더를 덧붙인다.
MAC 헤더: 이더넷용 헤더, MAC 주소
IP 헤더: IP용 헤더, IP 주소

  1. 만든 패킷을 네트워크용 하드웨어인 랜 어댑터(이더넷, 무선LAN)에 건네준다.
  2. 전기나 빛의 신호상태로 바뀌어 케이블에 송출

IP가 패킷을 송/수신하는 동작은 제어 패킷이던지, 데이터의 패킷이던지 패킷의 역할에 상관없이 모두 같다. 단지 데이터 조각을 한 덩어리의 바이너리 데이터로 간주하여 송수신 동작을 실행한다.

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

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

  • 수신처 IP 주소: TCP 담당 부분에서 통지된 통신 상대의 IP주소를 설정
    • 넘겨 받은 주소에 그대로 송신 작업을 수행하고, 판단하지 않는다.
  • 송신처 IP 주소: 송신처가 되는 LAN 어댑터를 판단하여 주소를 설정(LAN 어댑터가 여러개 있는 컴퓨터도 있기 때문에)

(프로토콜 스택의 IP담당 부분과 라우터의 패킷을 송수신하는 부분은 둘 다 IP의 규칙에 따라 패킷을 송수신하므로 같은 방법을 사용하여 동작한다.)

경로표

패킷을 건네줄 상대는 IP용 표 경료표(라우팅 테이블)을 보고 결정한다.(이에 대한 자세한 내용은 3장에서 설명) ****

  • 소켓에 기록되어 있는 수신처 IP 주소를 경로표의 Network Destination 항목과 비교하여 어느행에 해당하는지 찾는다.
  • 넷마스크: 넷마스크
  • Interface : 어댑터 등의 네트워크용 인터페이스를 나타냄
  • Gateway: TCP/IP 세계에서 라우터를 가리키는 용어. 다음 라우터의 IP 주소를 기입한다.
    • interface와 gateway의 주소가 같으면, 라우터로 중계하지 않고 상대에게 직접 패킷을 전할 수 있는것
  • 경로표의 제일 위에는 목적지와 넷마스크가 0.0.0.0인 행이 있는데, 기본 게이트웨이를 나타내며 다른곳에 일치하는것이 없으면 이행에 해당하는것으로 간주함
  • 프로토콜 번호: 패킷이 들어간 내용물이 어디에서 의뢰받은 것인지를 나타냄
    • TCP이면 06, UDP이면 17 등 (16진수 표기)

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

IP헤더를 만들었으면, 그 앞에 MAC 헤더를 붙인다. 이더넷은 TCP/IP와 다른 구조로 패킷의 수신처를 판단하기 때문에 그때 필요한 것이 MAC 헤더이다.

  • MAC주소
    • 48비트, 6바이트로 이루어져있으며, 무슨동 몇번지의 개념과 같이 계층이 있는 IP와는 다르게 값 전체가 하나의 의미만을 지닌다.
  • 이더타입
    • 이더넷의 내용물을 나타냄
      • 0800 - IP 프로토콜
      • 0806 - ARP 프로토콜
  • 송신처 MAC 주소: LAN 어댑터의 MAC 주소를 설정한다.(LAN어댑터를 제조할 때 ROM에 기록됨)
  • 수신처 MAC 주소: 경로표에서 찾은 일치하는 행의 Gateway 항목에 기록되어 있는 IP주소에 패킷을 보내야한다. 하지만 MAC주소는 어떻게 알 수 있을까? 다음 장에서 설명한다.

5. ARP로 수신처 라우터의 MAC 주소를 설정한다.

이더넷에는 연결되어 있는 전원에게 패킷을 전달하는 브로드캐스트라는 구조가 있는데, 이 구조를 이용하여 해당하는 IP주소를 어디서 갖고 있는지 질의한다.

  • ARP 캐시: 패킷을 보낼 때 마다 이동작을 하면 ARP의 패킷이 불어나기 때문에 이 영역에 저장해놓는다. ARP 캐시에 조회결과가 없는 경우에만 ARP를 조회한다. ARP 캐시에 저장된 값은 시간이 지나면(몇 분 정도) 삭제하도록 동작한다.(주소가 바뀌었을 수도 있기 때문에)
    • 그렇기에 IP 주소를 다시 설정한 직후에는 오류가 발생할 수 있다.(수동으로 ARP 캐시 내용을 삭제해 줘야함)

이렇게 찾는 MAC 주소를 이용하여 MAC헤더를 붙이면 패킷이 완성되고, IP담당 부분의 역할은 여기까지이다.

  • LAN 어댑터는 단순히 패킷을 송신하기만 하면 되기 때문에, IP이외의 특수한 패킷도 한개의 LAN 어댑터로 대응할 수 있다는 장점이 있다.

6. 이더넷의 기본

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

(c)가 현재의 이더넷 형태이다

기존에 전원에게 신호가 전달되는 방식에서, 스위칭 허브를 사용해서 수신처에만 신호를 전달하도록 설계되었다.

이더넷에 접속된 기기는 이더넷이라는 하나의 사양에 기초해서 동작하기 때문에 PC, 서버, 라우터를 포함한 모든 기기에 공통적으로 적용된다(무선LAN도 동일). 패킷의 내용물을 보지 않기 때문에 TCP의 동작단계, 애플리케이션에 종류에도 영향을 받지 않고 동일하다

7. IP 패킷을 전기나 빛의 신호로 변환하여 송신한다

이 동작은 LAN 어댑터가 실행한다.

LAN 어댑터의 초기화

전원을 공급하여 OS를 시동할 때 LAN 드라이버가 하드웨어의 초기화 작업을 수행해야 사용 가능한 상태가 된다. 이더넷 송/수신 동작을 제어하는 MAC라는 회로에 MAC 주소를 설정해야 한다.

MAC: Media Access Control

맥 어댑터의 ROM에는 전 세계적으로 중복되지 않고 일원화해서 관리하는 MAC 주소를 제조시에 기록하므로 이것을 랜드라이버가 MAC 회로에 주소값을 설정하게 된다.

8. 패킷에 3개의 제어용 데이터를 추가한다.

랜 드라이버는 IP 담당부분에서 패킷을 넘겨받으면 그것을 LAN어댑터의 버퍼 메모리에 복사한다. 복사를 마친 후 패킷을 송신하도록 MAC 회로에 명령을 보내면 작업이 시작된다.

MAC 회로는 먼저 송신패킷을 버퍼 메모리에서 추출하고, 맨 앞에 프리앰블스타트 프레임 딜리미터(SFD)라는 두개의 데이터를, 맨 끝에는 프레임 체크 시퀀스(FCS)라는 오류 검출용 데이터를 부가한다.

  • 프리앰블: 송신하는 패킷을 읽을 때의 타이밍을 잡기 위한것. 1과 0이 번갈아 나타나는 비트열이 56비트 이어진 것. 신호로 바꾸면 파형이 일정한 신호가 된다.

이더넷의 표준 사양을 정하는 IEEE라는 단체는 “패킷” 대신 “프레임” 이라는 용어를 사용하는데, 이더넷 계층의 용어중에 프레임이 등장하면 패킷과 동의어라고 생각하자.

디지털 데이터를 전기 신호로 나타낼 때는 0과 1의 비트 값을 전압이나 전류의 값에 대응시킨다. 그러면 아래 그림의 (a)와 같은 전기 신호로 디지털 데이터를 표현할 수 있다.

(a)의 우측과 같이 1과 0이 이어지면 신호의 변화가 없어 비트 구분을 할수 없게 되는데 이를 해결하기 위해 클록이라는 신호를 보내서 해결한다. 데이터 신호와 클록의 신호를 한개로 합성하여 보내고 수신측에서는 클록신호를 추출하여 원래의 데이터 신호를 얻을 수 있다. 이때 클록신호의 타이밍(변화하는 주기)을 판단하는것이 중요한데, 이러한 타이밍을 알려주기 위한 것이 바로 프리앰블의 역할이다.

  • 스타트 프레임 딜리미터: 패킷의 시작을 나타내는 표시
  • FCS: 패킷을 운반하는 도중 잡음 등의 영향으로 파형이 흐트러질 때 이것을 검출하기 위해 사용. 32비트의 비트열이며, 패킷의 맨앞부터 맨 끝까지의 내용을 특정 계산식을 이용해 계산한것이다.(CRC라고 불리는 디스크 장치 등에 사용하는 오류검사코드와 같은 종류) 1비트라도 변화하면 계산한 결과값도 달라진 값을 취하도록 고안이 되어있다. 따라서 FCS 값이 변화하면 파형이 변했다고 생각할 수 있다.

9. 허브를 향해 패킷을 송신한다.

위의 과정을 통해 케이블에 송출하는 패킷이 완성되면 신호를 송신해야하는데 이는 2가지 방식으로 나뉜다.

리피터 허브를 사용하는 반이중 모드

신호의 충돌을 피하기 위해 다음과 같이 동작한다.

  1. 케이블에 다른 기기가 송신한 신호가 흐르고 있는지 조사하고, 신호가 흐르고 있으면 그것이 끝날 때 까지 기다림
  2. 신호가 정지했거나 신호가 흐르고있지 않으면 송신동작을 시작
  3. MAC 회로가 프리앰블의 맨 앞부터 1비트씩 차례로 디지털 데이터를 전기신호로 변환하고, PHYMAU라는 송수신 신호 부분에 보낸다. 이때 디지털 데이터를 신호로 변환하는 속도가 곧 전송속도이다.
    • 다시말해, LAN 어댑터의 MAC 회로가 공통 형식의(어떤 이더넷의 신호형식에도 대응하는) 신호를 만들고 PHY(MAU) 회로가 케이블에 송출하는 형식으로 변환하여 케이블에 송신한다.
  4. PHY(MAU) 회로는 이 신호를 케이블에 송출하는 형식으로 변환하여 송신한다. PHY(MAU)회로는 MAC 회로가 송신한 신호의 형식을 변환하는 변환회로이다. 단지 송신 동작만 실행하는 것이아니라, 수신 신호선에서 신호가 흘러들어오는지를 감시한다.
  • 이더넷은 송신 상대에게 신호가 완전하게 도착했는지 확인하지 않는다. 이더넷 사양에서 기기 사이를 연결하는 케이블의 길이를 100m 이내로 정하는데, 길이가 짧아 오류가 좀처럼 발생하지 않을 뿐만 아니라 오류가 발생해도 TCP단에서 검출하기 때문에 확인할 필요가 없다.
  • 신호를 송신하는 도중에 수신 신호가 들어오게 되면 서로의 신호가 섞여서 분간할 수 없는 상태가 되고 이를 “충돌”이라고 부른다.
    • 충돌이 발생하면 “재밍 신호”라는 특수한 신호를 잠시 흘리고 기다렸다가 다시 한번 송신 동작을 시도한다. 충돌을 일으킨 기기의 대기시간이 동일하다면 다시 충돌이 일어날 수도 있으므로 대기 시간이 중복되지 않도록 고안되어있다.(MAC주소를 바탕으로 한 난수를 기준)
    • 충돌이 일어날 때 마다 대기시간을 2배씩 늘리다가 10번째 까지 보내도 해결되지 않으면 오류로 판단한다.

스위칭 허브를 사용한 전이중 모드

3장에서 알아본다. 송신과 수신을 동시에 실행하기 때문에 충돌이 일어나지 않는다.

10. 돌아온 패킷을 받는다.

리피터 허브를 이용한 반이중 동작의 이더넷에서는 1대가 송신한 신호가 리피터 허브에 접속된 케이블 전부에 흘러간다.

  1. 프리앰블로 파형에서 타이밍을 계산해서 스타트 프레임 딜리미터가 나오면, 그 다음 비트부터 디지털 데이터로 변환하여 동작을 개시한다.
  2. PHY(MAU) 회로에서 신호를 공통형식으로 변환하여 MAC 회로로 보낸다.
  3. MAC 회로에서 신호를 디지털 데이터로 변환하여 버퍼메모리에 저장한다.
  4. 신호의 마지막에서 FCS를 검사하고, 일치하지 않으면 오류패킷으로 간주하여 폐기한다.
  5. FCS에 문제가 없으면 다음에는 MAC 헤더의 수신처 MAC주소를 조사하여 자신의 MAC주소와 비교한 후 자신에게 오는 것인지 판단한다.
  6. 아니면 폐기하고 맞으면 패킷을 받아 버퍼 메모리에 저장한다.
  7. 패킷을 수신한 사실을 컴퓨터에 통지한다.
    • 인터럽트를 걸어 알림(OS)
    • LAN 어댑터 → 확장버스슬롯 → 인터럽트용 신호선 → 인터럽트 컨트롤러 → CPU
  8. 인터럽트에 의해 랜드라이버가 동작하고 LAN 어댑터의 버퍼 메모리에서 수신한 패킷을 추출하면, LAN 드라이버는 MAC헤더의 타입 필드에서 프로토콜을 판별한다.
  9. 프로토콜이 TCP/IP 면 TCP/IP의 프로토콜 스택에 패킷을 건네준다.

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

  1. IP 담당 부분은 IP 헤더 부분을 조사해 포맷에 문제가 없는지 확인하고, 수신처 IP를 조사한다.
    • IP가 다르면 오류이다.(PC는 패킷을 중계할 일이 없기 때문에)
      • 오류가 발생하면 IP담당 부분이 ICMP라는 메시지를 사용하여 통신 상대에게 오류를 통지(Destination unreachable)
  1. IP프로토콜에는 조각나누기 라는 기능이 있는데, 수신한 패킷이 분할된 패킷이면 그 패킷을 원래 패킷으로 되돌려야 한다. 플래크 값을 확인하여 분할된 패킷이라면 IP담당 내부의 메모리에 일시적으로 보관하고, IP헤더의 ID 정보에 갗은 값을 가진 다른 패킷이 도착하기를 기다린다. 모두 도착하면 원래의 패킷으로 되돌리는데 이 동작을 리어셈블링이라고 한다.
    1. 플래그: 헤더에서 조각이 나눠졌는지 여부를 알 수 있게하는 값
    2. 프래그먼트 오프셋: 패킷이 원래 패킷의 몇번째 위치에 있는지 나타내는 값
  2. TCP 담당 부분은 이 패킷을 건네받아 IP부분의 송수신 IP주소 및 TCP의 송수신 포트번호 4가지 값을 확인하여 해당하는 소켓을 찾는다. 소켓을 찾으면 통신 진행 상태가 기록되어 있으므로 그에따라 적절한 동작을 실행한다.(6장에서 자세히 설명하지만, TCP 부분이 IP주소의 값까지 확인하는 이유는 프로그램의 효율성을 위한 융통성있는 역할 분담이라고 생각하자. TCP 담당부분과 IP담당부분은 하나의 프로그램으로 묶여있는 경우가 많다.)

6. UDP 프로토콜을 이용한 송수신 동작

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

TCP는 도착한 패킷은 다시보내지 않고 오류로 도착하지 않는 패킷만 다시 보내는 구조를 가지고 있다. 하지만, 한개의 패킷만 보내는 경우는 데이터를 전부 다 보낸 후 수신측에서 응답 확인을 받아도 비효율적이지 않다. 또한 TCP의 구조를 사용하지 않으면 접속, 해제 시 필요한 제어용 패킷을 주고받는 과정도 필요없어진다.

2. 제어용 짧은 데이터

DNS 서버에 대한 조회 등 제어용으로 실행하는 정보 교환은 한개의 패킷으로 끝나는 경우가 많으므로 UDP를 사용한다. UDP는 수신확인, 윈도우 기능이 없어서 제어정보를 주고받을 필요가 없고, 접속이나 연결끊기 단계도 없다. 오류가 발생해 패킷이 없어져도 무시한다. 오류가 발생하면 회답이 돌아오지 않기 때문에 애플리케이션이 데이터를 한번 더 보내면 그만이다.

  • UDP로 송신할 수 있는 최대 데이터의 길이를 계산하는것은 TCP의 MTU나 MSS와는 다르다. MTU나 MSS는 이더넷이나 통신회선등의 패킷 최대길이를 바탕으로 산출하지만, IP 패킷의 최대 길이는 IP 헤더의 “전체길이” 필드 값으로 결정되기 때문이다. IP패킷의 최대길이(16비트, 65,535) - IP헤더(20), UDP 헤더(8) 이므로 65,50bytes 이다.(실제로 회선에 수용할 수 없으므로 IP단의 조각나누기 기능으로 실현하게됨)

3. 음성 및 동영상 데이터

음성이나 영상 데이터는 결정된 시간 안에 데이터를 건네주어야 한다. 데이터의 도착이 지연되면 타이밍이 어긋나 음성이 끊기거나 영상이 멈춘다. 음성이나 영상에는 데이터가 다소 없어도 치명적인 문제가 되지 않는 성질이 있기 때문에 UDP를 사용하는것이 효과적이다.