서버에서 연결 끊고 소켓 말소, IP와 이더넷의 패킷 송·수신 동작
8. 서버에서 연결을 끊어 소켓을 말소한다
8-1. 데이터 보내기를 완료했을 때 연결을 끊는다
- 데이터 보내기를 완료한 쪽에서 연결 끊기 단계에 들어간다 (여기에서는 서버측에서 연결 끊기 단계에 들어가는 것으로 간주)
- 서버측 애플리케이션이 먼저 Socket 라이브러리의 close 호출 → 서버측의 프로토콜 스택이 TCP 헤더를 만들고, 여기에 연결 끊기 정보 설정
- 구체적으로는 FIN 비트에 1을 설정하고, IP 담당 부분에 의뢰하여 클라이언트에 송신 요청, 동시에 서버측 소켓에 연결 끊기 동작에 들어갔다는 정보 기록 ①
- 클라이언트 측 : 서버에서 FIN에 1을 설정한 TCP 헤더가 도착하면 클라이언트 측의 프로토콜 스택은 자신의 소켓에 서버측이 연결 끊기 동작에 들어갔다는 것을 기록
- 그리고 FIN을 1로 설정한 패킷을 받은 사실을 알리기 위해 ACK 번호를 서버측에 반송 ②
- 위 과정이 끝나면 애플리케이션이 데이터를 가지러 올 텐데 이 때 데이터를 건네지 않고 서버에서 보낸 데이터를 전부 수신 했다는 사실을 클라이언트 측에 알리고 종료
8-2. 소켓을 말소한다
- 연결이 종료되어도 소켓은 바로 말소되지 않고 잠시 기다린 후 말소한다
[연결 끊기 동작]
- 클라이언트가 FIN 송신
- 서버가 ACK 번호 송신
- 서버가 FIN 송신
- 클라이언트가 ACK 번호 송신
이 경우 서버는 ACK 번호가 돌아오지 않으면(유실 시) 다시 한 번 FIN을 보낼 수 있다. 이 때 클라이언트 소켓이 말소되고 다른 애플리케이션이 소켓을 작성하면 같은 포트 번호가 할당될 수 있다.
이렇게 같은 포트 번호의 소켓이 만들어진 상태에서 서버가 다시 보낸 FIN이 도착하면 어떻게 될까?
새로 할당된 새 소켓에 FIN이 도착할 수 있고 그럴 경우 원하지 않던 연결 끊기 동작이 실행될 수 있다.
8-3. 데이터 송·수신 동작 정리
- 데이터 송·수신에서 최초의 동작은 소켓을 작성하는 단계이다
- 소켓을 만들면 클라이언트에서 서버를 향해 접속 동작을 실행한다.
- ① 먼저 클라이언트가 SYN을 1로 만든 TCP 헤더를 만들어 서버에 보낸다
- ② 이것이 서버에 도착하면 서버에서 SYN을 1로 만든 TCP 헤더가 돌아온다
- 이 TCP 헤더에는 ① 헤더와 마찬가지로 시퀀스 번호와 윈도우가 기록되어 있고, ①의 TCP 헤더를 받은 것을 나타내는 ACK 번호도 기록되어 있다
- ③ 이것이 클라이언트에 도착하면 TCP 헤더를 받은 것을 나타내는 ACK 번호를 기록한 TCP 헤더를 받은 것을 나타내는 ACK 번호를 기록한 TCP 헤더를 클라이언트가 서버에 보낸다. 이것으로 접속 동작이 끝나고 데이터 송·수신 단계에 들어간다.
- 데이터 송·수신 단계에서 웹의 경우 클라이언트에서 서버에 리퀘스트 메시지를 보내는 것부터 시작한다
- ④ TCP는 이것을 적당한 크기의 조각으로 분할하고 TCP 헤더를 맨 앞에 부가하여 서버에 보낸다. TCP 헤더에 송신 데이터가 몇 번째 바이트부터 시작되는지를 나타내는 시퀀스 번호가 기록되어 있다
- ⑤ 이것이 서버에 도착하면 서버는 ACK 번호를 클라이언트에 반송한다
- 서버가 응답 메시지 보내기를 완료하면 데이터 송·수신 동작이 끝나므로 연결 끊기 동작에 진입한다.
- 웹의 경우 서버에서 연결 끊기 동작에 들어갈 것이다. 거기에서는 먼저 FIN을 1로 만든 TCP 헤더가 흐르고 이것을 받았음을 나타내는 ACK 번호의 TCP 헤더가 돌아올 것이다. 이후 역방향으로 FIN을 1로 만든 TCP 헤더와 ACK 번호의 TCP헤더가 흐르다가 잠시 후 소켓이 말소된다.
9. IP와 이더넷의 패킷 송·수신 동작
9-1. 패킷의 기본
TCP 담당 부분은 접속, 송·수신, 연결 끊기의 각 단계에서 통신 상대와 대화할 때 IP 담당 부분에 의뢰하여 대화하는 데이터를 패킷의 모습으로 만들어 상대에게 도착한다. 이번에는 의뢰를 받은 IP 담당 부분이 어떻게 패킷을 상대에게 송신하는지 알아본다.
패킷은 '헤더'와 '데이터'의 두 부분으로 구성
- 헤더 : 수신처를 나타내는 주소 등의 제어 정보
- 데이터 : 내용
→ 먼저 패킷의 송신처가 되는 기기가 패킷을 만드는데, 헤더에는 적절한 제어 정보를 기록하고, 데이터 부분에는 얼마간의 데이터를 넣은 후 패킷을 가장 가까운 중계 장치에 송신한다. 이렇게 차례로 패킷을 중계하면 최종적으로 수신처의 기기에 패킷이 도착한다.
- 또한 송신처에서 수신처를 향해 패킷을 보내면 보통 수신처에서 송신처를 향해 회답 패킷이 되돌아온다.
- 어떤 시점에서는 송신처가 될 수도 있고 수신처가 될 수도 있기 때문에 구별하지 않고 묵어서 엔드노드라고 부른다.
[서브넷은 '라우터'와 '허브'라는 두 종류의 퍀ㅅ 중계 장치에서 역할을 분담하며 패킷을 운반한다]
- 라우터 : IP가 목적지를 확인하여 다음 IP의 중계 장치를 나타낸다. MAC 헤더 (이더넷용 헤더)
- 허브 : 서브넷 안에 있는 이더넷이 중계 장치까지 패킷을 운반한다 (IP용 헤더)
- 먼저 송신처에서 패킷의 목적지가 되는 액세스 대상 서버의 IP 주소를 IP 헤더의 수신처에 기록
- 이제 패킷의 목적지가 분명해지므로 거기에 패킷을 도착하도록 이더넷에 의뢰
- 이때 다음 라우터에 할당된 이더넷의 주소(MAC 주소)를 조사하고, 그것을 MAC 헤더에 기록
- 이렇게해서 의뢰를 받은 이더넷에게 어느 라우터에 패킷을 도착하면 좋은지 전달
- 이렇게 패킷을 전달하면 이더넷의 원리에 따라 움직이는 허브에 도착. 허브에서 이더넷의 헤더의 수신처 정보와 이더넷용 표를 결합해서 패킷의 목적지를 판단하여 중계
- 그러면 패킷은 다음 라우터에 도착. 라우터에는 IP용 표가 있으므로 이것과 IP 헤더의 수신처를 결합하면 다음에 어느 라우터에 패킷을 중계하면 좋을 지 결정. 그리고 다음 라우터에 패킷을 건네주기 위해 라우터의 MAC 주소를 조사하고, 이것을 MAC 헤더에 기록한다. MAC 헤더를 바꾸어 쓰면 되고,(그림 ③) 패킷을 다음 라우터에 송신
→ 이것이 TCP/IP 네트워크에서 패킷을 목적지까지 전달하는 동작의 전체 모습이다.
9-2. 패킷 송·수신 동작의 개요
- IP 담당 부분은 패킷을 상대에게 송출만 하기 때문에 그 뒤에 상대가 있는 곳까지 패킷을 운반하는 것은 허브나 라우터 같은 네트워크 기기의 역할이 되므로 IP 담당 부분은 패킷을 운반하는 동작 전체에서 입구 부분에 불과
- 패킷 송·수신 동작의 출발점은 TCP 담당 부분이 IP 담당 부분에 패킷 송신을 의뢰하는 곳부터 시작 ① TCP 담당 부분은 데이터 조각에 TCP 헤더를 부가한 것을 IP 담당 부분에 전달
- 이 의뢰를 받은 IP 담당 부분은 그 앞에 제어 정보를 기록한 IP 헤더와 MAC 헤더, 2개의 헤더를 부가. 여기까지 IP 담당 부분 역할
- IP 헤더 : IP 프로토콜에 규정된 규칙에 따라 IP 주소로 표시된 목적지까지 패킷을 전달할 때 사용하는 제어정보
- MAC 헤더 : LAN을 사용하여 가장 가까운 라우터까지 패킷을 운반할 때 사용하는 제어정보
- 이번에는 만든 패킷을 네트워크용 하드웨어 전달 ②
- 상대에게 패킷이 도착하면 거기에서 회답이 돌아온다. 케이블에서 LAN 어댑터에 들어온 패킷을 디지털 데이터의 모습으로 되돌린 후 IP 담당에게 전달 ③
- 그러면 IP 담당 부분이 MAC 헤더와 IP 헤더의 뒤에 이어지는 내용물, 즉 TCP 헤더와 데이터 조각을 TCP 담당 부분에게 전달 이후의 동작은 전에 게시한 글에서 소개한 TCP 담당 부분으로 넘어감
→ IP가 패킷을 송·수신하는 동작은 제어 패킷이든지, 데이터의 패킷이든지 패킷의 역할에 상관 없이 모두 같다. 내용은 간주하지 않고 송·수신 동작을 수행하기 때문
9-3. 수신처 IP 주소를 기록한 IP 헤더를 만든다
IP 담당 부분의 동작을 추적해본다.
- IP 담당 부분은 TCP 담당 부분에서 패킷 송·수신 의뢰를 받으면 IP 헤더를 만들어 TCP 헤더의 앞에 붙인다. 가장 중요한 것은 패킷을 어디로 전달해야 하는지를 나타내는 수신처 IP 주소이다
- IP 헤더의 수신처 IP 주소에는 통신 상대의 주소를 설정한다. 송신처 IP 주소는 송신처가 되는 LAN 어댑터를 판단하여 주소를 설정한다
9-4. 이더넷용 MAC 헤더를 만든다
IP 헤더를 만들었으면 IP 담당 부분의 앞에 MAC 헤더를 붙인다. 이더넷은 TCP/IP와 다른 구조로 패킷의 수신처를 판단하며 이더넷의 수신처 판단 구조로 사용하는 것이 MAC 헤더이다.
[MAC 헤더에 기록되는 항목]
필드 명칭 | 길이(비트) | 설명 |
수신처 MAC 주소 | 48 | 이 패킷을 전달하는 상대의 MAC 주소. LAN에서의 패킷 배송은 이 주소를 바탕으로 수행 |
송신처 MAC 주소 | 48 | 이 패킷을 송신한 측의 MAC 주소, 패킷을 받았을 때 이 값에 따라 누가 보냈는지 판단 |
이더 타입(Ether Type) | 16 | 사용하는 프로토콜 종류를 나타냄 |
수신처에 기록할 MAC 주소를 알아야하는데 누구에게 건네주어야 할 지 모르기 때문에 우선 패킷을 건네 줄 상대가 누구인지 'Gateway' 항목에서 IP주소를 찾는다. 이를 ARP를 사용하여 MAC 주소로 변환한다.
9-5. ARP로 수신처 라우터의 MAC 주소를 조사한다
상대가 자신과 같은 네트워크에 존재하면 이것으로 MAC 주소를 알 수 있다. 그러면 MAC 주소를 MAC 헤더에 설정하여 MAC 헤더를 만든다. 패킷을 보낼 때마다 이 동작을 하면 ARP의 패킷이 불어나기 때문에 한 번 조사한 결과는 ARP 캐시라는 메모리 영역에 보존하여 다시 이용한다.
MAC 헤더를 IP 헤더의 앞에 붙이면 패킷이 완성된다. 이렇게 해서 패킷을 만들기까지가 IP 담당 부분의 역할이다.
9-6. 이더넷 기본
이더넷은 다수의 컴퓨터가 여러 상대와 자유롭게 적은 비용으로 통신하기 위해 고안된 통신 기술이다.
MAC 헤더의 수신처 MAC 주소에 기억된 상대에게 패킷을 전달하고, 송신처 MAC 주소로 송신처를 나타낸 후 이더 타입으로 패킷의 내용물을 나타낸다는 성질이 이더넷의 고유 성질이다.
9-7. IP 패킷을 전기나 빛의 신호로 변환하여 송신
- IP가 만든 패킷은 메모리에 기억된 디지털 데이터이므로 이것을 그대로 상대에게 보낼 수 없다.
- 그래서 디지털 데이터를 전기나 빛의 신호로 변환하여 네트워크의 케이블에 송출하는데, 이것이 송·수신 동작의 본질이며 이것을 수행하는 것이 LAN 어댑터이다.
9-8. 패킷에 3개의 제어용 데이터를 추가
- MAC 회로는 먼저 송신 패킷을 버퍼 메모리에서 추출하고 맨 앞에는 프리앰블과 스타트 프레임 딜리미터라는 두 개의 데이터를, 맨 끝에는 프레임 체크 시퀀스(FCS)라는 오류 검출용 데이터를 부가한다
- 프리엠블 : 송신하는 패킷을 읽을 때의 타이밍을 잡기 위한 것
- 스타트 프레임 딜리미터 : 패킷의 시작을 나타내는 표시
- FCS : 패킷을 운반하는 도중에 잡음 등의 영향으로 파형이 흐트러져 데이터가 변한 경우 이것을 검출하기 위해 사용
9-9. 허브를 향해 패킷을 송신
프리앰블, 스타트 프레임 딜리미터, FCS의 세 가지를 부가하면 케이블에 송출하는 패킷이 완성된다.
신호를 송신하는 동작은 1) 리피터 허브를 사용했을 때 반이중 모드와 2) 허브를 사용한 전이중 모드가 존재
- 반이중 모드는 다른 기기가 송신한 신호가 흐르고 있는지 조사하고, 신호가 흐르고 있으면 그것이 끝날 때까지 기다린다.
- 송신 동작은 먼저 MAC 회로가 프리앰블의 맨 앞부터 1비트씩 차례로 디지털 데이터를 전기 신호로 변환하고, 이것을 PHY 또는 MAU라는 송·수신 신호 부분에 보낸다.
- PHY or MAU 허브 기능
- MAC 회로가 만든 신호를 케이블에 송출하는 형식으로 반환하여 케이블 송신
- 수신 신호선에서 신호가 흘러들어오는지 감시
- 신호를 송신하고 있는 사이 수신 신호가 흘러오지 않으면 되는데, 흘러들어오는 경우도 존재한다. 이것이 바로 충돌이라는 현상이다. 이렇게 되면 이상 송신을 계속해도 의미가 없으므로 송신 동작을 중지한다
- 그리고 충돌이 일어난 사실을 다른 기기에 알리기 위해 재밍 신호라는 특수한 신호를 잠시 동안 흘리고 나서 송신 동작을 멈추고 잠시 기다렸다가 다시 한 번 송신 동작을 시도한다.
- 충돌이 일어날 때마다 2배씩 대기 시간을 늘리다가 열 번째까지 다시 보냈는데도 해결되지 않으면 오류로 판단한다.
9-10. 돌아온 패킷을 받는다
패킷을 수신할 때의 동작이다. 수신 동작도 허브에 접속된 케이블 전부에 흘러가므로 이러한 신호를 전부 받아들이는 것부터 시작한다. FCS에 문제가 없으면 MAC 헤더의 수신처 MAC 주소를 조사하여 LAN 어댑터를 초기화할 때 설정한 자체의 MAC 주소와 비교한 후 이것이 자신에게 오는지 판단한다.
다른 곳에 갈 패킷은 수신할 필요가 없으므로 폐기하고, 수신처 MAC 주소가 자신에게 오는 것인 경우에만 패킷을 받아 버퍼 메모리에 저장한다. 이렇게 해서 MAC 회로가 할 일이 끝나면 패킷을 수신한 사실을 컴퓨터 본체에 통지하는데 이 통지는 인터럽트라는 구조를 사용한다.
컴퓨터 본체는 패킷의 도착을 알아차리지 못하므로 컴퓨터 본체가 실행하고 있는 작업에 끼어들어 LAN 어댑터 쪽에 주의시키는 것이 인터럽트이다.
9-11. 서버의 응답 패킷을 IP에서 TCP로 넘긴다
서버에서 반송된 패킷을 LAN 드라이버는 TCP/IP의 프로토콜 스택에 건넬 것이다. 그러면 IP 담당 부분은 IP 헤더 부분부터 오류가 있는지 검사한다. 오류가 발생했을 때는 IP 담당 부분이 ICMP라는 메시지를 사용하여 통신 상대에게 오류를 통지하게 되어있다.
- 수신처 IP 주소가 올바르면 이것을 수신하지만, 이때 할 일이 한 가지 더 있다. IP 프로토콜에는 조각 나누기(fragmentation) 기능이 있다.
- 만약 수신한 패킷이 분할된 것이면 IP 담당 부분은 그것을 원래 패킷으로 되돌린다. 분할된 패킷은 IP 헤더에 있는 플래그라는 항목을 보면 알 수 있으므로 수신 패킷이 분할된 것이면 IP 담당 부분은 그것을 원래 패킷으로 되돌린다.
- 분할된 패킷은 IP 헤더에 있는 플래그라는 항목을 보면 알 수 있으므로 수신 패킷이 분할된 것이면 IP 담당 부분 내부의 메모리에 일시적으로 보관한다.
- 그리고 IP 헤더에 있는 ID 정보에 같은 값을 가진 패킷이 모두 도착하면 패킷을 원래의 모습으로 되돌린다. 이를 리어셈블링(reassembling)이라고 한다.
- 리어셈블링이 끝나면 패킷을 TCP 담당 부분에 건네준다.
10. UDP 프로토콜을 이용한 송·수신 동작
10-1. 수정 송신이 필요없는 데이터의 송신이나 제어용 짧은 데이터는 UDP가 효율적이다
TCP가 복잡한 이유는 패킷 송·수신 과정에서 데이터를 확실히 전달하기 위해 ACK 신호를 이용하여 오류가 검출되었을 경우 해당하는 패킷만 재전송하는 과정이 존재하기 때문이다.
UDP는 데이터 재전송이 필요할 경우 해당하는 경우만 재전송하는 것이 아닌 전체 패킷을 재전송한다. 이는 여러 개의 통신이 있을 때는 비효율적일 수 있으나 수정 송신이 필요없는 하나의 통신일 경우 효율적일 수 있다.
그래서 DNS 서버에서 정보 교환은 한 개의 패킷으로 끝나는 경우가 많으므로 TCP가 아니라 UDP를 사용한다.
10-2. 음성 및 동영상 데이터
음성이나 영상의 데이터를 보낼 때도 UDP를 사용한다. 이는 결정된 시간 안에 데이터를 송신하지 않으면 재생 타이밍이 맞지 않거나 중간에 끊길 수 있기 때문에 빠른 속도가 요구된다.
※ 지금까지 데이터를 송·수신 할 때 OS의 내부에 있는 프로토콜 스탯이 어떻게 움직이는지, 또한 LAN 어댑터에서 패킷이 어떻게 전기 신호로 변환되어 케이블에서 나가는지를 살펴보았다.
다음 게시글은 케이블에 나간 패킷이 리피터 허브, 스위칭 허브, 라우터라는 기기를 경유하여 인터넷으로 나가는 부분까지 알아본다.