diff --git "a/chapter2/\354\241\260\353\257\274\354\204\234.md" "b/chapter2/\354\241\260\353\257\274\354\204\234.md" index 8b13789..fe1751c 100644 --- "a/chapter2/\354\241\260\353\257\274\354\204\234.md" +++ "b/chapter2/\354\241\260\353\257\274\354\204\234.md" @@ -1 +1,563 @@ +# Chapter 2. 프로토콜 스택, LAN 어댑터 +### `TCP/IP의 데이터를 전기 신호로 만들어 보낸다.` + +![50E94EEA-BBB2-4210-BA3B-1C78914F3B65.jpeg](Chapter%202%20%E1%84%91%E1%85%B3%E1%84%85%E1%85%A9%E1%84%90%E1%85%A9%E1%84%8F%E1%85%A9%E1%86%AF%20%E1%84%89%E1%85%B3%E1%84%90%E1%85%A2%E1%86%A8,%20LAN%20%E1%84%8B%E1%85%A5%E1%84%83%E1%85%A2%E1%86%B8%E1%84%90%E1%85%A5%20aab0a2a847d4472387b4a38aa8e9ffcb/50E94EEA-BBB2-4210-BA3B-1C78914F3B65.jpeg) + +1. 소켓을 작성한다 +2. 서버에 접속한다 +3. 데이터를 송수신한다 +4. 서버에서 연결을 끊어 소켓을 말소한다 +5. IP와 이더넷 패킷 송수신 동작 +6. UDP 프로토콜을 이용한 송수신 동작 + +--- + +# Story 1. 소켓을 작성한다. + +![4B879FE5-646B-4011-A231-1C4C72C7251D.jpeg](Chapter%202%20%E1%84%91%E1%85%B3%E1%84%85%E1%85%A9%E1%84%90%E1%85%A9%E1%84%8F%E1%85%A9%E1%86%AF%20%E1%84%89%E1%85%B3%E1%84%90%E1%85%A2%E1%86%A8,%20LAN%20%E1%84%8B%E1%85%A5%E1%84%83%E1%85%A2%E1%86%B8%E1%84%90%E1%85%A5%20aab0a2a847d4472387b4a38aa8e9ffcb/4B879FE5-646B-4011-A231-1C4C72C7251D.jpeg) + +위 그림의 상하관계는 작업을 의뢰하는 쪽이 위에 있고, 의뢰를 받아 작업 하는 쪽이 아래에 있습니다. + +### 네트워크 애플리케이션 (응용 계층) + +Socket 라이브러리가 있으며, 그 안에는 `리졸버`가 내장되어 있습니다. + +### OS (전송 계층) + +OS 내부를 나타내며, `프로토콜 스택`이 있습니다. + +프로토콜 스택 윗 부분에는 `TCP`와 `UDP`라는 프로토콜을 사용하여 데이터 송수신을 담당하는 부분이 있고, + +- 브라우저나 메일등의 일반적인 애플리케이션이 데이터를 송수신할 경우에는 `TCP` +- DNS 서버에 대한 조회 등에서 짧은 제어용 데이터를 송수신 할 경우에는 `UDP` + +그 아래에는 `IP` 프로토콜을 사용하여 패킷 송수신을 담당합니다. + +인터넷에서 데이터를 운반할 때는 데이터를 작게 나누어 패킷 형태로 운반하는데, 이 패킷을 통신 상대까지 운반 하는 것이 IP의 주 역할 입니다. + +IP안에는 `ICMP` 와 `ARP`라는 프로토콜을 다루는 부분이 포함되어 있습니다. + +- **ICMP** : 패킷을 운반할 때 발생하는 오류를 통지하거나 제어용 매시지를 통지할 때 사용 +- **ARP** : IP 주소에 대응하는 이더넷의 MAC 주소를 조사할 때 사용 + +### LAN 드라이버 (인터넷 계층) + +LAN 드라이버는 LAN 어댑터의 하드웨어를 제어 합니다. + +### LAN 어댑터 (네트워크 접근 계층) + +LAN 어댑터가 실제 송수신 동작, 즉 케이블에 대해 신호를 송수신 하는 동작을 실행 합니다. + +### 프로토콜 스택 + +프로토콜 스택은 내부에 제어 정보를 기록하는 메모리 영역(버퍼메모리)을 가지고 있고, 대표적인 제어 정보는 통신 상대의 IP 주소, 포트 번호, 통신 현재 진행 상태 등이 있다. Story2에서 자세히 알아보자. + +프로토콜 스택은 소켓에 기록된 제어 정보를 참조하면서 동작합니다. + +![583302A5-23F6-4A0D-A9A9-AA329896D41E.jpeg](Chapter%202%20%E1%84%91%E1%85%B3%E1%84%85%E1%85%A9%E1%84%90%E1%85%A9%E1%84%8F%E1%85%A9%E1%86%AF%20%E1%84%89%E1%85%B3%E1%84%90%E1%85%A2%E1%86%A8,%20LAN%20%E1%84%8B%E1%85%A5%E1%84%83%E1%85%A2%E1%86%B8%E1%84%90%E1%85%A5%20aab0a2a847d4472387b4a38aa8e9ffcb/583302A5-23F6-4A0D-A9A9-AA329896D41E.jpeg) + +--- + +# Story 2. 서버에 접속한다 + +접속의 첫번째 동작은 통신 상대와 `제어 정보`를 주고 받아 소켓에 필요한 정보를 기록하고 `데이터를 송수신이 가능한 상태`로 만들어야 합니다. + +예를 들어, 클라이언트의 IP 주소나 포트 번호를 서버측에 알리는 것이 제어 정보를 주고 받는것의 예시 입니다. + +제어 정보는 데이터를 송수신 동작을 제어하기 위한 정보이며, 통신의 규칙으로 정해져 있습니다. + +데이터 송수신을 하기 위해서는 데이터를 일시적으로 저장하는 메모리 영역이 필요한데, 이 영역을 `버퍼 메모리` 라고 부르고, 버퍼 메모리 확보도 접속할 때 이뤄집니다. + +### 제어 정보 종류 + +![A043AFBB-D8C5-4222-AF14-811CAFDE8144.jpeg](Chapter%202%20%E1%84%91%E1%85%B3%E1%84%85%E1%85%A9%E1%84%90%E1%85%A9%E1%84%8F%E1%85%A9%E1%86%AF%20%E1%84%89%E1%85%B3%E1%84%90%E1%85%A2%E1%86%A8,%20LAN%20%E1%84%8B%E1%85%A5%E1%84%83%E1%85%A2%E1%86%B8%E1%84%90%E1%85%A5%20aab0a2a847d4472387b4a38aa8e9ffcb/A043AFBB-D8C5-4222-AF14-811CAFDE8144.jpeg) + +위 표에 나와 있는 항목이 제어 정보로 규정되어 있습니다. `제어 정보는 프로토콜 스택 안에 있는 소켓의 메모리 영역에 기록합니다.` + +**접속, 송신, 수신, 연결 끊기** 각 단계에서 클라이언트와 서버가 대화 할 때 마다 거기에 이 제어 정보를 부가 합니다. 아래 예시를 보자. + +![7ED853E9-3884-4443-B207-968ED639D530.jpeg](Chapter%202%20%E1%84%91%E1%85%B3%E1%84%85%E1%85%A9%E1%84%90%E1%85%A9%E1%84%8F%E1%85%A9%E1%86%AF%20%E1%84%89%E1%85%B3%E1%84%90%E1%85%A2%E1%86%A8,%20LAN%20%E1%84%8B%E1%85%A5%E1%84%83%E1%85%A2%E1%86%B8%E1%84%90%E1%85%A5%20aab0a2a847d4472387b4a38aa8e9ffcb/7ED853E9-3884-4443-B207-968ED639D530.jpeg) + +예를 들어, 그림 a와 같이 클라이언트와 서버 사이에 주고받는 패킷 맨 앞부분에 제어 정보를 부가 (데이터 앞)합니다. + +**접속 동작 단계**에는 아직 데이터 송수신이 이루어지지 않으므로, + +그림 b는 데이터가 없고 패킷의 내용은 제어 정보로만 이루어져 있습니다. 이 제어 정보를 패킷의 맨 앞부분에 배치하는 곳부터 `헤더` 라고 부릅니다. + +**이더넷 헤더(MAC 헤더), IP 헤더, TCP 헤더**와 같이 여러 종류가 있습니다. + +--- + +# Story 3. 데이터를 송수신 한다. + +수신측: 프로토콜 스택에서 애플리케이션으로 데이터를 보냄 + +송신측: 프로토콜 스택에서 TCP헤더, IP헤더, MAC헤더를 붙여서 2계층으로 전송 + +## 3-1. 프로토콜 스택에 HTTP 리퀘스트 메시지를 넘긴다 + +프로토콜 스택은 애플리케이션에게 받은 데이터의 내용을 알지 못합니다. 단지 바이너리 데이터가 1바이트씩 차례대로 나열되어 있음을 인식할 뿐입니다. + +프로토콜 스택은 데이터를 곧바로 송신하지 않고 `버퍼 메모리`에 저장하고, 애플리케이션이 다음 데이터를 보내기를 기다립니다. + +버퍼 메모리에 저장하는 양은 애플리케이션 종류나 만드는 방법에 따라 다릅니다. + +데이터를 버퍼 메모리에 모아 한꺼번에 송신하는 경우도 있고, 1바이트씩 또는 1행씩 세분하여 송신 의뢰하는 경우도 있습니다. + +데이터를 곧바로 보내는 방법은 작은 패킷을 많이 보내야 하므로 네트워크 이용 효율이 저하되므로 어느 정도 데이터를 모아서 송신하는 것이 효율적입니다. + +### **그럼 데이터를 얼마나 모아서 송신하는거지? (MTU, MSS)** + +![39BC81ED-FDD5-42CE-96E6-42F8C28B2532.jpeg](Chapter%202%20%E1%84%91%E1%85%B3%E1%84%85%E1%85%A9%E1%84%90%E1%85%A9%E1%84%8F%E1%85%A9%E1%86%AF%20%E1%84%89%E1%85%B3%E1%84%90%E1%85%A2%E1%86%A8,%20LAN%20%E1%84%8B%E1%85%A5%E1%84%83%E1%85%A2%E1%86%B8%E1%84%90%E1%85%A5%20aab0a2a847d4472387b4a38aa8e9ffcb/39BC81ED-FDD5-42CE-96E6-42F8C28B2532.jpeg) + +판단 요소 중 하나는 `한 패킷에 저장할 수 있는 데이터의 크기`입니다. + +프로토콜 스택은 `MTU`라는 매개변수를 바탕으로 판단합니다. + +**MTU(Maximum Transmission Unit)**: 한 패킷으로 운반 할 수 있는 디지털 최대길이로 이더넷 에서는 보통 1500바이트입니다. 이 MTU의 맨 앞부분에는 헤더가 포함되는데, 이 헤더 부분을 뺀 영역이 데이터 최대 길이가 됩니다. 이것을 `MSS`라고 합니다. + +**MSS(Maximum segment Size)**: 데이터 최대 길이, 애플리케이션에서 받은 데이터가 MSS를 초과하거나 MSS에 가까운 길이에 이르기까지 데이터를 저장하고 송신동작을 하면 패킷이 잘게 나누어질 걱정을 할 필요가 없다. + +- MTU : 패킷 한개로 운반할 수 있는 디지털 데이터의 최대 길이, 이더넷 에서는 보통 1500바이트 +- MSS : 헤더를 제외하고 한 개의 패킷으로 운반할 수 있는 TCP의 데이터 최대 길이 + +### 근데 데이터가 언제까지 올지 어떻게 알아? 애플리케이션이 송신 속도가 느려지면? + +또 한가지 판단 요소는 `타이밍`입니다. 애플리케이션의 송신 속도가 느려지는 경우 MSS에 가깝게 데이터를 저장하면 여기에서 시간이 걸려 송신이 지연됩니다. + +그래서 버퍼에 데이터가 모이지 않아도 적당한 시점에 송신을 해야합니다. 따라서 프로토콜 스택은 내부에 타이머가 있어서 이것으로 일정 시간 이상 경과하면 패킷을 송신합니다. + +### 3-1 정리 + +이처럼 프로토콜스택에서 네트워크로 데이터를 보내는 판단 요소는 `한 패킷에 저장될 수 있는 최대 크기`와 `타이밍`이 있습니다. + +전자를 중시하면 패킷의 길이가 길어져서 네트워크 이용 효율이 높아지지만 버퍼에 머무는 시간만틈 송신 동작이 지연될 우려가 있습니다. + +반대로 후자를 중시허면 지연은 적어지지만 이용 효율이 떨어지므로 양자를 절충해서 적당히 시간을 가늠하여 송신 동작을 실행해야 합니다 + +TCP 프로토콜 사양에는 절충에 관한 규정은 없으며, 실제로 어떻게 판단해야 할지는 프로토콜 스택을 만드는 개발자에게 맡겨져 있습니다. 그러므로 OS 종류나 버전에 따라 달라집니다. + +하지만 애플리케이션측에서도 송신의 타이밍을 제어할 수 있습니다. 송신을 의뢰할 때 옵션에 “버퍼에 머물지 않고 바로 송신할 것”이라고 지정하면 프로토콜 스택은 바로 송신 동작을 합니다. + +## 3-2. 데이터가 클 때는 분할하여 보낸다. + +![3329BC29-CD1A-4D19-84E3-DF2814D8060E.jpeg](Chapter%202%20%E1%84%91%E1%85%B3%E1%84%85%E1%85%A9%E1%84%90%E1%85%A9%E1%84%8F%E1%85%A9%E1%86%AF%20%E1%84%89%E1%85%B3%E1%84%90%E1%85%A2%E1%86%A8,%20LAN%20%E1%84%8B%E1%85%A5%E1%84%83%E1%85%A2%E1%86%B8%E1%84%90%E1%85%A5%20aab0a2a847d4472387b4a38aa8e9ffcb/3329BC29-CD1A-4D19-84E3-DF2814D8060E.jpeg) + +애플리케이션에서 보낸 데이터의 길이가 MSS의 길이를 초과하면, 다음 데이터를 기다리지 않고 송신 버퍼에 들어있는 데이터를 맨 앞부터 차례대로 MSS의 크기에 맞게 분할합니다. 이후 분할한 조각을 한 개씩 패킷에 넣어 송신합니다. + +순서를 주의 합시다. 데이터를 받은 후 쪼개는 것이 아니라, 애플리케이션에게 데이터를 받기 전에 먼저 MSS 크기에 맞게 분할 하고 맨 앞에 TCP 헤더를 붙여줍니다. + +그리고 소켓에 기록되어 있는 제어 정보를 바탕으로 송신처 포트번호나 수신처 포트 번호등 필요한 항목을 시록하고, IP 담당 부분에 건네주어 송신 동작을 실행합니다. + +## 3-3. ACK 번호를 사용하여 패킷이 도착했는지 확인한다 + +### 위에서 데이터가 크면 분할 한다고 했는데 몇번째 데이터인지 어떻게 알지? + +TCP 담당 부분은 데이터를 조각으로 분할할 때 해당 데이터의 몇번짜 바이트에 해당하는지 세어둡니다. + +그리고 데이터의 조각를 송신할 때 세어둔 값을 TCP헤더에 기록하는데, 이것을 `시퀀스 번호`라고 합니다. + +- 데이터의 크기: 패킷전체크기 - 헤더크기 + +![7F64EE68-A5A2-407C-8E29-DF4DB9323EE5.jpeg](Chapter%202%20%E1%84%91%E1%85%B3%E1%84%85%E1%85%A9%E1%84%90%E1%85%A9%E1%84%8F%E1%85%A9%E1%86%AF%20%E1%84%89%E1%85%B3%E1%84%90%E1%85%A2%E1%86%A8,%20LAN%20%E1%84%8B%E1%85%A5%E1%84%83%E1%85%A2%E1%86%B8%E1%84%90%E1%85%A5%20aab0a2a847d4472387b4a38aa8e9ffcb/7F64EE68-A5A2-407C-8E29-DF4DB9323EE5.jpeg) + +실제로는 보안적인 이유로 시퀀스 번호를 1부터 시작하지 않고 난수를 바탕으로 초기값을 설정합니다. + +접속 동작에서 SYN 제어비트를 1로 설정할 때 시퀀스 번호에도 값을 설정하여 난수로된 시퀀스 번호의 초깃값을 알려줍니다. + +### 시퀀스 번호 + ACK 번호를 통한 강력한 구조 + +이런 구조는 수신측에 패킷이 올바르게 도착하지 않으면 단순히 다시 보내므로 네트워크 어디에서 오류가 발생했는지 알 필요도 없고 조치할 필요도 없습니다. + +그냥 단순히 아직 안온 시퀀스 번호만 다시 보내면 됩니다. + +이 때문에 `LAN 어댑터, 버퍼, 라우터` 모두 회복 조치를 취하지 않습니다. 오류를 검출하면 그 패킷을 버리기만 하는데, `애플리케이션`도 마찬가지 입니다. TCP에 맡겨두면 오류가 발생해도 데이터가 문제 없이 상대에게 도착합니다. + +단, 도중에 케이블이 분리되거나 서버가 다운되는 등의 이유로 TCP가 아무리 다시 보내고 데이터가 도착하지 않는 경우가 있습니다. TCP에서 보통 10번을 보내도 ACK 번호가 오지 않으면 TCP는 데이터 송신 동작을 종료하고 애플리케이션에 오류를 통지합니다. + +- 시퀀스 번호와 ACK번호로 패킷이 수신측에 도찻한 것을 확인합니다. + +## 3-4. 패킷 평균 왕복 시간으로 ACK 번호의 대기 시간을 조정한다 + +### 그럼 TCP는 ACK 번호를 몇초 동안 기다릴까? + +ACK 번호가 돌아오는 것을 기다리는 대기 시간을 `타임아웃 값`이라고 합니다 + +네트워크가 혼잡하여 정체가 일어나면 ACK 번호가 돌아오는 것이 지연되므로 이것을 예측하여 `대기 시간을 어느 정도 길게 설정`해야 합니다. 그러지 않으면 ACK 번호가 돌아오기전에 다시 보내야 하는 사태가 발생합니다. + +이 `소모적인 다시 보내기`는 단순히 낭비의 문제가 아닙니다. 혼잡한 네트워크에 패킷을 계속 다시 보내면 네트워크의 혼잡을 더더욱 악화시킵니다. + +그렇다고 `대기시간이 긴게 좋은 것은 아닙니다.` 대기 시간이 길어지면 패킷을 다시 보내는 동작이 지연되어 속도 저하의 원인이 됩니다. + +### 실제 TCP는 ACK 대기시간을 어떻게 설정 했을까? + +실제 TCP는 타임아웃 값을 `동적으로 변경하는 방법`을 취하고 있습니다. 데이터 송신 동작을 실행할 때 항상 ACK 번호가 돌아오는 시간을 기록해두고, ACK 번호가 돌아오는 시간이 지연되면 이것에 대응하여 대기시간을 늘리고, 반대로 ACK 번호가 곧바로 돌아오면 대기 시간을 짧게 설정합니다. + +- 대기시간에 많은 영향을 끼치는 요소로는 서버가 가까운지, 먼지에 따라 차이가 큽니다. 예를 들어 사내 LAN이면 수 밀리초안에, 인터넷의 경우 혼잡하면 수백 밀리초를 넘는 경우도 있습니다. +- 컴퓨터의 시간 계측은 정밀도가 낮으므로 너무 짧은 시간에 ACK 번호가 돌아오면 정확히 계측할 수 없다. 그래서 대기 시간 최솟값을 정해두는데 OS 종류에 따라 0.5초에서 1초 정도로 설정되어 있다. +- 위에서 말했듯이 인터넷이 혼잡한 경우에 수백밀초 이므로 보통 이 최소 대기시간도 넘지 못한다. + +## 3-5. 윈도우 제어 방식으로 효율적으로 ACK 번호를 관리한다. + +### 윈도우 제어방식이란 + +![D60AFE71-2C68-4AEE-B82E-2FC1E015FD19.jpeg](Chapter%202%20%E1%84%91%E1%85%B3%E1%84%85%E1%85%A9%E1%84%90%E1%85%A9%E1%84%8F%E1%85%A9%E1%86%AF%20%E1%84%89%E1%85%B3%E1%84%90%E1%85%A2%E1%86%A8,%20LAN%20%E1%84%8B%E1%85%A5%E1%84%83%E1%85%A2%E1%86%B8%E1%84%90%E1%85%A5%20aab0a2a847d4472387b4a38aa8e9ffcb/D60AFE71-2C68-4AEE-B82E-2FC1E015FD19.jpeg) + +그림 a와 같이 한 개의 패킷을 보내고 ACK 번호를 기다리는 방법은 ACK 번호가 돌아올 때까지 아무것도 하지 않으므로 시간 낭비입니다. + +이런 낭비를 줄이기 위해 그림 b와 같은 `윈도우 제어 방식`을 이용합니다. + +`윈도우 제어`는 한 개의 패킷을 보내는게 아니라, ACK 번호를 기다리지 않고 차례대로 연속해서 여러개의 패킷을 보내는 방법입니다. 그러면 ACK 번호가 돌아올 때 까지 시간이 낭비되지 않습니다. + +### 윈도우 제어방식의 주의할 점 + +- 핑퐁 방식은 수신 처리가 끝난 후 ACK 번호를 돌려보내고, ACK 번호를 받고 나서 송신측이 다음패킷을 보내므로 수신측의 능력을 초과하여 패킷을 보낼 일이 없음. +- 그러나 윈도우 제어방식은 ACK 번호를 기다리지 않고 연속해서 패킷을 보내면 수신측의 능력을 초과할 수 있음. + +![C731F5C8-D7C0-4E5C-B19A-57CFD43D27D9.jpeg](Chapter%202%20%E1%84%91%E1%85%B3%E1%84%85%E1%85%A9%E1%84%90%E1%85%A9%E1%84%8F%E1%85%A9%E1%86%AF%20%E1%84%89%E1%85%B3%E1%84%90%E1%85%A2%E1%86%A8,%20LAN%20%E1%84%8B%E1%85%A5%E1%84%83%E1%85%A2%E1%86%B8%E1%84%90%E1%85%A5%20aab0a2a847d4472387b4a38aa8e9ffcb/C731F5C8-D7C0-4E5C-B19A-57CFD43D27D9.jpeg) + +1. 수신측의 TCP는 패킷을 수신하면 일단 수신용 버퍼 메모리에 데이터를 일시 보관합니다. +2. 수신측에서는 ACK 번호를 계산하거나 조각을 연결하여 원래 데이터를 복원한 후 애플리케이션에 건네주어야 합니다. +3. 현재 패킷 처리가 끝나지 않은 상태에서 다음 패킷이 도착해도 곤란하지 않도록 수신 버퍼를 설치하고, 여기에 수신된 데이터를 일시 보관 합니다. + +그런데 애플리케이션에 건네주는 속도보다 빠른 속도로 데이터가 도착하면 수신 버퍼에 데이터가 쌓이다가 넘칩니다. 이렇게 넘친 데이터는 패킷이 도착해도 오류가 발생한것처럼 처리 되는데, 이것은 수신측의 능력을 초과한다는 의미 입니다. + +### 윈도우 제어방식 수신측의 능력을 초과하는것을 해결 방법 + +그래서 수신 처리가 끝나고 수신 버퍼에 빈 부분이 생기면 그 분량만큼 수신할 수 있는 데이터양을 늘리므로 TCP 헤더의 `윈도우필드`에서 이것을 송신측에 알립니다. + +## 3-6. ACK 번호와 윈도우를 합승한다. + +송수신 동작의 효율성을 높이기 위해 `ACK 번호`와 `윈도우를 통지하는 타이밍`을 고려해야 합니다. + +- ACK 번호를 통지하는 타이밍 + +수신측에서 데이터를 받았을때 내용을 조사하여 정상 수신을 확인할 수 있는 경우에만 송신측에 보냅니다. 즉 데이터를 수신한후 즉시 보내면 됩니다. + +- 수신측 윈도우 버퍼 크기를 통지하는 타이밍 + +수신측에서 애플리케이션에 데이터를 건네주고 수신 버퍼의 빈 영역이 늘어났을 때 이것을 송신측에 통지해야 하는데, 이것이 윈도우 통지의 타이밍 입니다. + +### 그러면 ACK 번호랑 윈도우 버퍼 크기를 따로 보내? 너무 비효율적인데? + +두가지를 종합해보면 수신동작이 정상적으로 완료되었을 때 ACK 번호를 송신측에 통지하고, 잠시후 데이터를 애플리케이션에 건네주었을 때 윈도우를 송신측에 통지합니다. + +이렇게 하면 데이터의 패킷을 수신할 때 마다 ACK번호와 윈도우 통지 패킷을 하나씩 따로따로 송신하므로 패킷이 많아져서 비효율적입니다. + +따라서 수신측은 ACK 번호나 윈도우를 통지할 때 소켓을 바로 보내지 않고 잠시 기다립니다. 기다리는 사이에 통지 동작이 일어나면 두개를 한개의 패킷으로 묶어서 같이 보냅니다. + +ACK번호 1개 윈도우 1개 뿐만 아니라 + +여러개의 ACK번호가 연속해서 일어난 경우, + +여러개의 윈도우 통지가 연속해서 일어난 경우(수신 버퍼의 빈 영역이 점점 늘어나고 있는 상황)도 한번에 묶어서 보낼 수 있습니다. + +## Story 3 정리 + +- 수신측 프로토콜 스택 과정 + +먼저 수신한 데이터 조각과 TCP 헤더의 내용을 조사하여 도중에 데이터가 누락되었는지 검사하고, 문제가 없으면 ACK 번호를 반송합니다. 그리고 데이터 조각을 수신 버퍼에 일시 보관하고, 조각들을 연결하여 데이터를 원래 모습으로 복원한 후 애플리케이션에 건네줍니다. 애플리케이션에 데이터를 건네주고 나서 타이밍을 가늠하여 윈도우를 송신측에 통지합니다. + +이 과정에서 ACK번호와 윈도우를 따로따로 통지하여 패킷을 두번 보내는데 비효율적이여서, 실제로는 ACK번호가 도착하고 지정된 시간을 대기하는데, 이 대기 시간 안에 윈도우 통지가 일어나면 ACK 번호와 수신측 윈도우 버퍼 사이즈를 한개의 패킷에 같이 보냅니다. + +--- + +# Story 4. 서버에서 연결을 끊어 소켓을 말소한다. + +![D1E1F8D6-573C-4D29-9520-F7492C2AB81F.jpeg](Chapter%202%20%E1%84%91%E1%85%B3%E1%84%85%E1%85%A9%E1%84%90%E1%85%A9%E1%84%8F%E1%85%A9%E1%86%AF%20%E1%84%89%E1%85%B3%E1%84%90%E1%85%A2%E1%86%A8,%20LAN%20%E1%84%8B%E1%85%A5%E1%84%83%E1%85%A2%E1%86%B8%E1%84%90%E1%85%A5%20aab0a2a847d4472387b4a38aa8e9ffcb/D1E1F8D6-573C-4D29-9520-F7492C2AB81F.jpeg) + +HTTP 1.0 프로토콜을 사용한 경우에는 keep alive 기능이 없어 클라이언트가 데이터를 요청하고 서버가 응답을 하면 바로 연결을 끊었으므로 항상 서버가 연결 끊기 작업을 했습니다. 위 사진이 그런 경우입니다. + +하지만 HTTP 1.1 프로토콜부터는 서버가 응답 메시지를 반송한 후 계속 클라이언트가 요청 메시지를 보내도 됩니다. 이 경우 요청 메시지가 없으면 클라이언트는 먼저 연결 끊기 작업에 들어갈 수 있습니다. + +### **서버에서 연결 끊기 단계 시작하는 과정** + +1. 서버측의 애플리케이션의 소켓 close 호출 +2. 서버 프로토콜 스택에서 TCP 헤더 부착 후, 컨트롤 비트 FIN 비트를 1로 설정 +3. IP 담당 부분에 의뢰하여 클라이언트에 송신 요청 +4. 서버에서 FIN을 1로 설정한 TCP 헤더가 클라이언트측 프로토콜 스택(TCP)에 도착 +5. 패킷에 오류가 없으면 FIN을 1로 설정한 패킷을 받은 사실을 ACK 번호를 통해 알림 +6. 서버는 패킷을 보내면 클라이언트에서 데이터 요청을 할 때 까지 기다림.(fin비트 보내고 바로 종료하지 않음 → 요청을 더할 수 있으므로) +7. 클라이언트측 애플리케이션도 데이터 다 보냈으면 close 호출 +8. 클라이언트 프로토콜스택은 FIN 비트를 1로 설정한 TCP 헤더를 만들고 IP 담당 부분에 의뢰하여 서버에 송신 +9. 서버는 요청에 대한 데이터를 다 보냈으면 ACK 번호를 반송하고 아니면 데이터를 보냄. + +### 연결 끊었으니 바로 소켓 말소하면 되나? + +결론 부터 말하면 소켓을 즉시 말소하지 않고 잠시 시다립니다. + +예를 들어 아래와 같은 과정이 있다. + +1. 클라이언트 FIN 송신 +2. 서버가 ACK 번호 송신 +3. 서버가 FIN 송신 +4. 클라이언트가 ACK 번호 송신 + +클라이언트 ACK 번호가 말소되면 어떻게 될까? + +일단 서버는 FIN을 계속 송신을 한다. 몇분이 경과하면 회복 전망이 없는 것으로 판단되어 멈춘다. 뭐 이런 경우는 괜찮다. + +근데 만약에 다른 애플리케이션이 소켓을 작성하면 새 소켓에 같은 포트번호가 할당 될 수 있는데, 서버가 보낸 FIN이 이 새로운 소켓에 도착하면 새로운 소켓의 연결이 끊길것이다. + +그래서 연결을 끊더라도 소켓을 즉지 말소하지 않고 잠시 기다립니다. + +### TCP 전체 동작 + +![D1EC9AAA-9B1D-49DD-AE64-569EC7458705.jpeg](Chapter%202%20%E1%84%91%E1%85%B3%E1%84%85%E1%85%A9%E1%84%90%E1%85%A9%E1%84%8F%E1%85%A9%E1%86%AF%20%E1%84%89%E1%85%B3%E1%84%90%E1%85%A2%E1%86%A8,%20LAN%20%E1%84%8B%E1%85%A5%E1%84%83%E1%85%A2%E1%86%B8%E1%84%90%E1%85%A5%20aab0a2a847d4472387b4a38aa8e9ffcb/D1EC9AAA-9B1D-49DD-AE64-569EC7458705.jpeg) + +--- + +# Stroy 5. IP와 이더넷의 패킷 송수신 동작 + +![A668461C-77B8-4E68-8BAC-6D3A5B6AF671.jpeg](Chapter%202%20%E1%84%91%E1%85%B3%E1%84%85%E1%85%A9%E1%84%90%E1%85%A9%E1%84%8F%E1%85%A9%E1%86%AF%20%E1%84%89%E1%85%B3%E1%84%90%E1%85%A2%E1%86%A8,%20LAN%20%E1%84%8B%E1%85%A5%E1%84%83%E1%85%A2%E1%86%B8%E1%84%90%E1%85%A5%20aab0a2a847d4472387b4a38aa8e9ffcb/A668461C-77B8-4E68-8BAC-6D3A5B6AF671.jpeg) + +패킷은 헤더와 데이터 두 부분으로 구성 됩니다. + +MAC 헤더: 이더넷의 제어 정보 (이더넷 용 헤더) + +IP헤더: IP의 제어 정보 (IP용 헤더) + +### TCP 헤더는 데이터를 검사했지? + +TCP 헤더는 데이터를 나누고 조립하고 에러 검사를 수행하는 등의 기능을 수행합니다. + +### 그럼 MAC헤더랑 IP헤더는 어디다 써? + +![DF30B6D9-A189-4708-9A37-52512BD53104.jpeg](Chapter%202%20%E1%84%91%E1%85%B3%E1%84%85%E1%85%A9%E1%84%90%E1%85%A9%E1%84%8F%E1%85%A9%E1%86%AF%20%E1%84%89%E1%85%B3%E1%84%90%E1%85%A2%E1%86%A8,%20LAN%20%E1%84%8B%E1%85%A5%E1%84%83%E1%85%A2%E1%86%B8%E1%84%90%E1%85%A5%20aab0a2a847d4472387b4a38aa8e9ffcb/DF30B6D9-A189-4708-9A37-52512BD53104.jpeg) + + 우선 허브는 이더넷의 규칙에 따라 패킷을 운반하고, + +라우터는 IP의 규칙에 따라 패킷을 운반 합니다. + +- 서브넷 안에 있는 이더넷이 중계 장치 까지 패킷을 운반합니다. `(허브)` +- IP가 목적지를 확인하여 다음 IP의 중계 장치를 나타냅니다. `(라우터)` + +![0AE2662E-16A6-4121-AA3A-F487E3504EBD.jpeg](Chapter%202%20%E1%84%91%E1%85%B3%E1%84%85%E1%85%A9%E1%84%90%E1%85%A9%E1%84%8F%E1%85%A9%E1%86%AF%20%E1%84%89%E1%85%B3%E1%84%90%E1%85%A2%E1%86%A8,%20LAN%20%E1%84%8B%E1%85%A5%E1%84%83%E1%85%A2%E1%86%B8%E1%84%90%E1%85%A5%20aab0a2a847d4472387b4a38aa8e9ffcb/0AE2662E-16A6-4121-AA3A-F487E3504EBD.jpeg) + +1. 우선 이더넷의 원리에 따라 허브에 도착합니다. +2. 위의 사진은 허브가 한개지만 허브가 여러개면 계속 MAC 헤더를 통해 허브를 따라가다 라우터에 도착합니다. +3. 라우터에는 IP용 표가 있으므로 이것과 IP 헤더의 수신처를 결합해서 어느 라우터에 패킷을 중계할지 결정 합니다. +4. 라우터를 결정하고 라우터의 MAC 주소를 찾아 원래 있던 MAC 헤더(R1)는 버리고 새로운 MAC 헤더(R2)를 붙입니다. +5. 그럼 또 MAC 헤더의 주소를 따라 허브에 도착하고 1~4번 과정을 반복하면 패킷은 목적지에 도착할 것입니다. + +이더넷 부분은 다른것으로 대체할 수 있습니다. 무선 LAN, ADSL, FTTH 등 IP의 의뢰를 받아 패킷을 운반할 수 있는 것이면 무엇이든 이더넷을 대체할 수 있습니다. + +### 패킷 송수신 동작 + +![B07F785C-8CFA-4D95-AF55-0880E6543F94.jpeg](Chapter%202%20%E1%84%91%E1%85%B3%E1%84%85%E1%85%A9%E1%84%90%E1%85%A9%E1%84%8F%E1%85%A9%E1%86%AF%20%E1%84%89%E1%85%B3%E1%84%90%E1%85%A2%E1%86%A8,%20LAN%20%E1%84%8B%E1%85%A5%E1%84%83%E1%85%A2%E1%86%B8%E1%84%90%E1%85%A5%20aab0a2a847d4472387b4a38aa8e9ffcb/B07F785C-8CFA-4D95-AF55-0880E6543F94.jpeg) + +1. 프로토콜 스택에서 TCP 담당은 TCP 헤더를 붙이고 프로토콜스택 IP 담당에 송신합니다 +2. IP 담당은 패킷에 IP헤더와 MAC 헤더를 붙이고 TCP/IP 2계층인 랜 드라이버(이더넷, 무선 LAN등)에 0과1로 이루어진 디지털 데이터를 전송합니다. +3. 이것이 1계층인 LAN 어댑터에 의해 전기나 빛의 신호 상태로 바뀌어 케이블에 송출되고, 신호는 허브나 라우터 등의 중계장치를 통해 패킷이 목적지에 도착합니다. + +참고 - IP가 패킷을 송수신 하는 동작은 TCP 헤더 제어 패킷만 있든, 데이터 패킷이 있든 상관없이 모두 같음(안의 내용물은 모르고 그냥 전송만 하는 역할) + +### IP 헤더 포맷 + +![AD8719A8-41A0-4E94-8E7B-BE3D38F6EFD7.jpeg](Chapter%202%20%E1%84%91%E1%85%B3%E1%84%85%E1%85%A9%E1%84%90%E1%85%A9%E1%84%8F%E1%85%A9%E1%86%AF%20%E1%84%89%E1%85%B3%E1%84%90%E1%85%A2%E1%86%A8,%20LAN%20%E1%84%8B%E1%85%A5%E1%84%83%E1%85%A2%E1%86%B8%E1%84%90%E1%85%A5%20aab0a2a847d4472387b4a38aa8e9ffcb/AD8719A8-41A0-4E94-8E7B-BE3D38F6EFD7.jpeg) + +**수신처 IP 주소** + +IP는 스스로 수신처를 판단하지 않고 애플리케이션이 지정한 상대에게 패킷을 송신할 뿐이므로 애플리케이션이 IP를 잘못 지정해도 그 IP 주소를 그대로 IP 헤더에 설정합니다. + +**송신처 IP 주소** + +보통의 경우 LAN 어댑터가 하나이므로 컴퓨터에 할당된 IP 주소를 할당하면 되지만, + +여러개의 LAN 어댑터가 장착되있으면, 여러개의 서로 다른 IP 주소가 할당됩니다. 이 경우에는 어떤 IP 주소를 할당할 지 선택해야 합니다. + +이것은 `패킷을 건네주는 상대의 라우터를 결정하는 것과 같습니다.` 상대의 라우터가 결정되면 LAN 어댑터에서 패킷을 송신해야 하는지 결정되며, LAN 어댑터가 결정되면 IP 주소가 결정되기 때문입니다. + +- IP 헤더의 수신처 IP 주소에는 통신 상대의 주소를 설정합니다. +- 송신처 IP 주소는 송신처가 되는 LAN 어댑터를 판단하여 주소를 설정합니다. + +### 그럼 패킷을 건네줄 상대를 어떻게 판단해? + +![D1B3A575-A23F-4B4C-9C67-A34E8DF81C34.jpeg](Chapter%202%20%E1%84%91%E1%85%B3%E1%84%85%E1%85%A9%E1%84%90%E1%85%A9%E1%84%8F%E1%85%A9%E1%86%AF%20%E1%84%89%E1%85%B3%E1%84%90%E1%85%A2%E1%86%A8,%20LAN%20%E1%84%8B%E1%85%A5%E1%84%83%E1%85%A2%E1%86%B8%E1%84%90%E1%85%A5%20aab0a2a847d4472387b4a38aa8e9ffcb/D1B3A575-A23F-4B4C-9C67-A34E8DF81C34.jpeg) + +이 IP용 표를 경로표라고 하는데, 이게 바로 `라우팅 테이블`이다. 이 표를 기준으로 판단한다. + +3장에서 자세히 알아보자. + +## MAC 헤더 포맷 + +![7B7B6441-FD98-45F8-9F64-E6BAD8E1BF8F.jpeg](Chapter%202%20%E1%84%91%E1%85%B3%E1%84%85%E1%85%A9%E1%84%90%E1%85%A9%E1%84%8F%E1%85%A9%E1%86%AF%20%E1%84%89%E1%85%B3%E1%84%90%E1%85%A2%E1%86%A8,%20LAN%20%E1%84%8B%E1%85%A5%E1%84%83%E1%85%A2%E1%86%B8%E1%84%90%E1%85%A5%20aab0a2a847d4472387b4a38aa8e9ffcb/7B7B6441-FD98-45F8-9F64-E6BAD8E1BF8F.jpeg) + +**송신처 MAC 주소** + +MAC 주소는 랜 어댑터를 제조할 때 그 안에 ROM에 기록됨 + +실제로 MAC 주소를 읽어오는 것은 OS를 기동하여 LAN 어댑터를 초기화할 때 한 번뿐입니다. 여기에서 읽어 온 MAC 주소를 메모리에 보관해 두고 송신 동작을 할 때는 메모리에 보관해 둔 값을 MAC 헤더에 설정합니다. + +이 동작은 LAN 드라이버가 수행하므로 LAN 드라이버를 설정하여 ROM에서 읽는 대신 설정 파일에 설정 해 둔 MAC 주소를 읽어와서 메모리에 보관해 두고 이것을 MAC 헤더에 설정할 수 있습니다. 또한 명령으로 입력한 MAC 주소를 메모리에 보관해 두고 MAC 헤더에 설정할 수도 있습니다 + +**수신처 MAC 주소** + +- IP 담당 부분은 라우팅 테이블의 `Gateway` 항목의 값에서 패킷을 건네줄 상대를 판단합니다. + +여기에서 사용하는것이 `ARP`입니다. + +![1B89A33E-8186-443A-AD72-331DFF8BDF17.jpeg](Chapter%202%20%E1%84%91%E1%85%B3%E1%84%85%E1%85%A9%E1%84%90%E1%85%A9%E1%84%8F%E1%85%A9%E1%86%AF%20%E1%84%89%E1%85%B3%E1%84%90%E1%85%A2%E1%86%A8,%20LAN%20%E1%84%8B%E1%85%A5%E1%84%83%E1%85%A2%E1%86%B8%E1%84%90%E1%85%A5%20aab0a2a847d4472387b4a38aa8e9ffcb/1B89A33E-8186-443A-AD72-331DFF8BDF17.jpeg) + +위 사진을 보자. + +이더넷에는 연결되어 있는 전원에게 패킷을 전달하는 `브로드캐스트` 구조가 되어 있습니다. + +ARP를 이용해 MAC 주소를 알아내면 MAC 주소를 MAC 헤더에 설정하여 MAC 헤더를 만듭니다. + +패킷을 보낼 때 마다 이 동작을 하면 ARP 패킷이 너무 많아지기 때문에 한 번 조사한 결과는 `ARP 캐시`라는 메모리 영역에 보존합니다. + +ARP 캐시의 저장된 값을 계속 사용하면 MAC 주소의 값과 ARP 캐시 값이 달라질 수 있으므로 몇 분이 지나면 무조건 삭제됩니다. 무조건 삭제하는 방법은 문제가 되지 않습니다. 단지 ARP 조회(브로드캐스트) 동작을 하면 됩니다. + +### 이더넷의 기본 + +![6B452894-065E-4426-9287-DD10213A241C.jpeg](Chapter%202%20%E1%84%91%E1%85%B3%E1%84%85%E1%85%A9%E1%84%90%E1%85%A9%E1%84%8F%E1%85%A9%E1%86%AF%20%E1%84%89%E1%85%B3%E1%84%90%E1%85%A2%E1%86%A8,%20LAN%20%E1%84%8B%E1%85%A5%E1%84%83%E1%85%A2%E1%86%B8%E1%84%90%E1%85%A5%20aab0a2a847d4472387b4a38aa8e9ffcb/6B452894-065E-4426-9287-DD10213A241C.jpeg) + +트랜시버: 케이블 사이에 신호를 흘리는 역할만 하며, 케이블과 같습니다. + +**(a):** 컴퓨터가 신호를 송신하면 케이블을 통해 네트워크 전체에 신호가 흐르고 모두에게 신호가 도착합니다. 신호 맨 앞부분에 수신처 주소를 적어두는데, 이때 해당하는 수신처는 수신하고 다른 기기는 패킷을 폐기합니다. + +**(b):** 이더넷 원형(a)가 (b)의 모습으로 변했습니다. + +- 트렁크 케이블 → 리피터 허브 +- 트랜시버 케이블 → 트위스트 페어 케이블 + +모습은 바뀌었지만 신호가 모두에게 전달된다는 성질은 똑같습니다. + +**(c): 현재 이더넷은 이와 같은 형태를 가리킵니다.** + +언뜻 보면 (b)와 비슷하지만 `스위칭 허브`는 모두에게 신호를 보내지 않습니다. 수신처 MAC 주소로 나타내는 원하는 기기가 존재하는 부분에만 신호가 흐르고, 다른 곳에는 신호가 흐르지 않습이다. + +그러나 수신처 MAC 주소의 상대에게 패킷이 전달된다는 점은 변하지 않으므로 MAC 헤더의 개념은 그대로입니다. + +a, b, c 모두 IP 담당에서 ARP 프로토콜로 브로드캐스를 통해 MAC 주소를 찾는 과정은 똑같고 패킷을 전송하는 방식에서 차이가 있음 + +- a, b: 모두에게 전송, 해당하지 않는 MAC 주소는 패킷 폐기 +- c: 해당하는 MAC 주소에만 전송 + +### 이더넷(MAC 헤더)의 성질 + +- 수신처 MAC 주소에 기억된 상대에게 패킷을 전달 +- 송신처 MAC 주소로 송신처를 나타냄. +- 이더 타입으로 패킷의 내용물을 나타냄. + +이더넷도 IP와 마찬가지로 패킷의 내용물은 보지 않으므로 이더넷의 송수신 동작은 TCP 동작 단계에 상관 없이 모든 것에 공통입니다. + +- IP 담당과 이더넷은 단지 패킷을 전송만 하는 역할 + +### IP가 만든 패킷은 디지털데이터인데 어떻게 보내? + +IP가 만든 패킷은 메모리에 기억된 디지털 데이터이므로 이것을 그대로 보낼 수 없습니다. + +그래서 디지털 데이터를 전기나 빛의 신호로 변환하여 네트워크 케이블에 송출하는데, 이게 송수신 동작의 본질입니다. + +이 동작을 실행하는 것이 1계층에 있는 `LAN 어댑터` 인데, LAN 어댑터를 제어하려면 2계층에 있는`LAN 드라이버` 소프트웨어가 필요합니다. + +드라이버 필요 여부는 LAN 어댑터에만 한정되지 않고 키보드, 마우스, 디스플레이 어댑터 등 모든 하드웨어에 공통입니다. + +![33BA6099-04EA-48FD-B555-B9F8FB56D76F.jpeg](Chapter%202%20%E1%84%91%E1%85%B3%E1%84%85%E1%85%A9%E1%84%90%E1%85%A9%E1%84%8F%E1%85%A9%E1%86%AF%20%E1%84%89%E1%85%B3%E1%84%90%E1%85%A2%E1%86%A8,%20LAN%20%E1%84%8B%E1%85%A5%E1%84%83%E1%85%A2%E1%86%B8%E1%84%90%E1%85%A5%20aab0a2a847d4472387b4a38aa8e9ffcb/33BA6099-04EA-48FD-B555-B9F8FB56D76F.jpeg) + +LAN 어댑터의 내부 구조(중요 구성만 개념적으로 나타낸) 입니다. MAC(media access control) + +### 디지털 데이터 패킷을 전기신호로 변환하는 방법 + +![B2B1208C-EFB6-4FAF-979B-9148119838B7.jpeg](Chapter%202%20%E1%84%91%E1%85%B3%E1%84%85%E1%85%A9%E1%84%90%E1%85%A9%E1%84%8F%E1%85%A9%E1%86%AF%20%E1%84%89%E1%85%B3%E1%84%90%E1%85%A2%E1%86%A8,%20LAN%20%E1%84%8B%E1%85%A5%E1%84%83%E1%85%A2%E1%86%B8%E1%84%90%E1%85%A5%20aab0a2a847d4472387b4a38aa8e9ffcb/B2B1208C-EFB6-4FAF-979B-9148119838B7.jpeg) + +**패킷에 3개의 제어용 데이터를 추가합니다.** + +맨 앞 + +- `프리앰블`: 연속된 패턴 ex)010101010… 을 통해서 클럭 타이밍을 맞춤. +- `스타트 프레임 딜리미터`: 프레임 개시 위치 발견(패킷의 시작을 나타내는 표시) + +맨 뒤 + +- `FCS(프레임 체크 시퀀스)`: 오류 검출용 데이터(CRC 등) + +![B57F413D-83F9-48F0-9D5C-0FC90FC75F64.jpeg](Chapter%202%20%E1%84%91%E1%85%B3%E1%84%85%E1%85%A9%E1%84%90%E1%85%A9%E1%84%8F%E1%85%A9%E1%86%AF%20%E1%84%89%E1%85%B3%E1%84%90%E1%85%A2%E1%86%A8,%20LAN%20%E1%84%8B%E1%85%A5%E1%84%83%E1%85%A2%E1%86%B8%E1%84%90%E1%85%A5%20aab0a2a847d4472387b4a38aa8e9ffcb/B57F413D-83F9-48F0-9D5C-0FC90FC75F64.jpeg) + +### 정리 + +리피터 허브를 이용한 반이중 동작의 이더넷에서는 1대가 송신한 신호가 리피터 허브에 접속된 케이블 전부에 흘러갑니다. 즉 자신뿐만 아니라 누군가가 신호를 보내면 그것이 전부 수신 신호선에서 흘러옵니다. 그러므로 수신 동작은 이러한 신호를 전부 받아들이는 것부터 시작합니다. +신호의 맨 앞에는 `프리앰블`이 있으므로 파형에서 타이밍을 계산하여 `스타트 프레임 달리미터`가 나오면, 그 다음 비트부터 디지털 데이터로 변환하여 동작 을 개시합니다. 이 동작은 송신할 때와 반대로 PHY(MAU) 회로에서 MAC 회로쪽으로 진행합니다. + +먼저 PHY(MAU) 회로에서 신호를 공통 형식으로 변환 하여 MAC 회로에 보내고, MAC 회로에서 신호를 맨 앞부터 차례대로 디지털 데이터로 변환하여 버퍼 메모리에 저장합니다. 그리고 신호의 마지막에 이르면 맨 끝의 `FCS`를 검사합니다. + +도중에 잡음 등의 영향을 받아 파형이 흐트러지면 둘의 FCS 값이 일치되지 않고 오류 패킷으로 간주하여 폐기합니다. + +FCS에 문제가 없으면 MAC 헤더의 수신처 MAC 주소를 조사하여 LAN 어댑터를 초기화할 때 설정한 자체의 MAC 주소와 비교한 후 이것이 자신에게 오는 것인지 판단합니다. + +수신처 MAC 주소와 LAN 어댑터 MAC 주소가 다르면 폐기하고, 수신처 MAC 주소가 자신에게 오는 것인 경우에만 패킷을 받아 버퍼 메모리에 저장합니다. 이렇게 해서 MAC 회로가 할 일이 끝나면 패킷을 수신한 사실을 컴퓨터 본체에 통지합니다. + +통지는 `인터럽트`방식을 사용합니다. LAN 어댑터가 확장 버스 슬롯부분에 있는 인터럽트용 신호선에 신호를 보냊니다. 이 신호선은 LAN 드라이버를 호출합니다. + +--- + +--- + +# Story 6. UDP 프로토콜을 이용한 송수신 동작 + +### UDP 헤더에 기록하는 제어 정보 + +![0AB0BBF7-4085-4BF7-A103-5AE21DCB0E65.jpeg](Chapter%202%20%E1%84%91%E1%85%B3%E1%84%85%E1%85%A9%E1%84%90%E1%85%A9%E1%84%8F%E1%85%A9%E1%86%AF%20%E1%84%89%E1%85%B3%E1%84%90%E1%85%A2%E1%86%A8,%20LAN%20%E1%84%8B%E1%85%A5%E1%84%83%E1%85%A2%E1%86%B8%E1%84%90%E1%85%A5%20aab0a2a847d4472387b4a38aa8e9ffcb/0AB0BBF7-4085-4BF7-A103-5AE21DCB0E65.jpeg) + +### UDP 특징 + +TCP 프로토콜은 데이터를 보내고 오류가 발생하면 어디부터 어디까지 도착했는지 또는 어디서부터 다시 보내야 하는지 등의 복잡한 일을 생각해야 합니다. + +하지만 UDP는 단지 데이터를 `전부` 보낸 후에 수신측에서 수신 응답을 받습니다. + +그러나 전부 보내는 방법을 산택하면 패킷이 한개만 없어져도 전체를 다시 보내므로 비효율적 입니다. 만약 패킷이 한개라면 없어져도 상관 없습니다. + +### DNS 서버는 UDP 프로토콜? + +DNS 서버에 대한 조회등 제어용으로 실행하는 정보 교환은 한 개의 패킷으로 끝나는 경우가 많으므로 UDP를 사용합니다. + +### UDP 프로토콜 데이터 최대 길이 + +UDP로 송신할 수 있는 데이터 최대 깋이는 IP 패킷 최대길이에서 IP헤더와 UDP 헤더를 뺀 길이가 됩니다. + +이것은 MTU나 MSS 와는 개념이 다릅니다. MTU나 MSS는 이더넷 패킷(보통 1500바이트)또는 통신 회선패킷 의 최대 길이를 바탕으로 산출하지만, IP 패킷 최대 길이는 IP 헤더의 `전체 길이(16비트)`로 결정됩니다. + +따라서 + +- IP 패킷 최대 길이 = 2^16-1 = 65535 바이트 +- IP 헤더 = 20 바이트 +- UDP 헤더 = 8바이트 + +UDP 프로토콜 최대 데이터 크기 = 65535-20-8 = 65507바이트 + +하지만 이처럼 큰 데이터는 이더넷이나 통신 회선의 패킷에 수용할 수 없으므로, IP 담당 부분이 `조각 나누기`기능을 통해 패킷을 분할하고 송신합니다. + +### 음성 및 동영상도 UDP? + +음성이나 영상 데이터를 보낼 때도 UDP를 사용합니다. + +TCP 프로토콜에서 음성이나 영상 데이터를 보내다가 오류를 검출해서 데이터를 다시 보내면 시간이 걸리므로 재생 타이밍이 맞지 않기 때문에 데이터가 도착해도 쓸모가 없습니다. + +그리고 음성이나 영상 데이터는 에러가 검출되어 패킷이 조금 없어져도 치명적인 문제가 발생하지 않음. → 단지 순간 ‘치직’하면서 소리만 끊김 영상인 경우는 영상이 잠깐 멈출 뿐. + +이와 같이 다시 보낼 팔요가 없거나 다시 보내도 쓸모 없으면 단순히 UDP로 데이터를 보내는게 효율적 입니다. + +### 정리 + +- udp 데이터 최대 송신길이가 65507 바이트잖아? 근데 어저피 이더넷이 1500바이트 밖에 전송을 못하는데 의미가 있어? + + UDP 데이터그램의 최대 크기는 65,507바이트이지만, 실제로 사용 가능한 최대 크기는 통상적으로 MTU(Maximum Transmission Unit) 값에 따라 결정됩니다. MTU는 전송 매체의 최대 크기로, 이더넷의 경우 1,500바이트 정도입니다. 따라서 UDP 데이터그램의 크기가 MTU보다 크다면, 해당 데이터그램은 여러 개의 패킷으로 분할되어 전송됩니다. + + 하지만 이더넷에서 전송할 수 있는 패킷의 크기는 1,500바이트이기 때문에, 큰 UDP 데이터그램을 전송할 때 여러 개의 패킷으로 분할하게 되면 오버헤드가 발생하게 됩니다. 이 오버헤드는 데이터그램의 크기와 전송하는 패킷의 수에 비례합니다. 따라서 UDP 데이터그램의 크기가 MTU보다 작은 경우, 패킷 분할이 발생하지 않기 때문에 오버헤드가 줄어들고 전송 속도도 개선될 수 있습니다. + + 따라서 UDP 데이터그램의 크기는 가능한 MTU 크기에 근접하게 설정하는 것이 좋습니다. 이를 통해 전송 속도를 최적화할 수 있습니다. + +- 그럼 udp는 한번에 전체를 보내 통신할 수 있다는 이점이 사라지는거 아니야? + + UDP는 전체 데이터를 한 번에 보낼 수 있지만, 이더넷과 같은 전송 매체에서 전송할 수 있는 데이터의 크기 제한으로 인해 전체 데이터를 한 번에 보내는 것은 실용적이지 않을 수 있습니다. + + UDP는 데이터 전송에 대한 신뢰성 검사나 재전송 기능을 제공하지 않으므로, 데이터를 분할하여 전송하는 방식은 TCP와 같은 다른 프로토콜과는 다릅니다. 그러나 UDP는 데이터를 신속하게 전송할 수 있는 빠른 속도와 낮은 지연 시간을 제공하므로, 일부 응용 프로그램에서는 데이터 크기를 조정하여 최적의 성능을 얻으려는 경향이 있습니다. + + 또한 UDP는 스트리밍 비디오나 오디오와 같은 실시간 응용 프로그램에서 사용될 때 특히 유용합니다. 이러한 응용 프로그램에서는 손실된 데이터 패킷이 일부 있더라도, 전체 데이터가 실시간으로 전송되는 것이 중요하기 때문입니다. 따라서, UDP는 데이터를 전송할 때 데이터 크기를 적절하게 조절하면서도, 실시간 데이터 전송을 보장하는 데에 큰 이점을 제공합니다. + + ex) 제어정보 크기가 1500바이트가 안되고 패킷이 1개인 DNS 서버 조회 + + ex) 커넥션을 하지 않으므로 실시간 속도가 중요한 영상 등