서버와 클라이언트가 데이터를 송수신하는 과정
- 소켓을 작성합니다.
- 서버에 접속합니다.
- 데이터를 송수신합니다.
- 서버에서 연결을 끊어 소켓을 말소합니다.
프로토콜 스택의 내부 구성
- 위의 그림 중 맨 위에 있는 것은 네트워크 애플리케이션으로 브라우저, 메일 SW, 웹 서버, 메일 서버 등의 프로그램이 여기 해당됩니다.
- 애플리케이션의 아랫부분에는 Socket 라이브러리가 있으며, 그 안에는 리졸버가 내장되어 있습니다. 리졸버가 DNS 서버에 조회하는 동작을 실행합니다.
- 그 아래는 OS의 내부를 나타내며, 여기에 프로토콜 스택이 있습니다.
- 프로토콜 스택의 윗부분에는 TCP라는 프로토콜을 사용하여 데이터 송수신을 담당하는 부분과 UDP라는 프로토콜을 사용하여 데이터 송수신을 담당하는 부분이 있으며, 이 두 개의 프로토콜이 애플리케이션에서 보낸 의뢰를 받아 송수신 동작을 실행합니다.
- 브라우저나 메일 등의 일반적인 애플리케이션은 TCP를 사용하여 데이터를 송수신합니다. 그리고 DNS 서버에 대한 조회 등에서 짧은 제어용 데이터를 송수신하는 경우에는 UDP를 사용합니다.
- 그 아래에는 IP 프로토콜을 사용하여 패킷 송수신 동작을 제어하는 부분이 있습니다. 인터넷에서는 데이터를 운반할 때는 데이터를 작게 나누어 패킷이라는 형태로 운반하는데, 이 패킷을 통신 상대까지 운반하는 것이 IP의 주 역할입니다.
- 패킷 : 네트워크에서 데이터는 수십 바이트에서 수천 바이트 정도의 작은 덩어리로 운반되는데 이렇게 분할된 데이터의 덩어리를 패킷이라고 합니다.
- 그리고 IP 안에는 ICMP와 ARP라는 프로토콜을 다루는 부분이 포함되어 있습니다.
- ICMP는 패킷을 운반할 때 발생하는 오류를 통지하거나 제어용 메시지를 통지할 때 사용합니다.
- ARP는 IP주소에 대응하는 이더넷의 MAC 주소(IEEE에서 표준화 된 LAN 방식의 기기가 사용하는 같은 형식의 주소)를 조사할 때 사용합니다.
- IP의 아래에 있는 LAN 드라이버는 LAN 어댑터의 하드웨어를 제어합니다.
- 그리고 그 아래에 있는 LAN 어댑터가 실제 송수신 동작, 즉 케이블에 대해 신호를 송수신하는 동작을 실행합니다.
소켓
- 프로토콜 스택은 내부에 제어 정보를 기록하는 메모리 영역을 가지고 있으며, 여기에 통신 동작을 제어하기 위한 제어 정보를 기록합니다.
- 대표적인 정보는 통신 상대의 IP 주소는 무엇인가, 포트 번호는 몇 번인가, 통신 동작이 어떤 진행 상태에 있는가 하는 것입니다.
- 소켓은 개념적인 것이어서 실체가 없으므로 제어 정보를 기록한 메모리 영역이 소켓의 실체라고 생각해도 좋습니다.
- 프로토콜 스택은 이 제어 정보를 참조하면서 동작합니다.
- 위의 그림의 내용의 한 행이 하나의 소켓에 해당합니다.
- 소켓을 만든다는 동작은 여기에 새로 한 행의 제어 정보를 추가하고 '여기부터 통신을 시작하는 곳'이라는 식으로 상태를 기록하거나 송수신 데이터를 일시적으로 저장하는 버퍼 메모리를 준비하는 등 통신을 준비하는 작업입니다.
- netstat 내용을 보면, 다섯 번째 행은 PID(프로그램의 식별 번호)가 1720인 프로그램이 118.42.2.212라는 IP 주소를 할당한 LAN 어댑터를 사용하여 222.233.53.144의 IP 주소를 할당한 상대와 통신하고 있습니다.
- 또한, 자신은 2477, 상대는 80이라는 포트 번호를 사용하는 것도 알 수 있습니다.
- 2477이라는 포트 번호는 윈도우의 파일 서버가 사용하는 것이며, 이것은 파일 서버에 접속되었다는 것을 알 수 있습니다.
- 다른 예는, 첫 번째 행 PID가 1200인 프로그램이 135번 포트에 누군가가 접속하기를 기다리고 있는 상태를 나타냅니다. 이 행은 로컬측도 원격 측도 IP 주소가 0.0.0.0으로 되어 있는데, 이것은 아직 통신이 시작되지 않았기 때문에 IP 주소가 정해져 있지 않은 것을 나타냅니다.
- 처음은 소켓을 만드는 단계입니다. (맨 앞의 리졸버 단계는 전에 다뤘으므로 생략)
- 위의 그림과 1과 같이 socket을 호출하여 소켓을 만들 것을 의뢰하면 프로토콜 스택은 의뢰에 따라 하나의 소켓을 만듭니다.
- 이 때 프로토콜 스택이 최초로 하는 일은 소켓 한 개 분량의 메모리 영역을 확보하는 것입니다. 소켓의 제어 정보를 기록하는 메모리 영역은 처음부터 존재하는 것이 아니므로 먼저 확보해 두어야 합니다.
- 이 시점에서 소켓은 작성된 직후라서 아직 송수신 동작이 시작되지 않은 초기 상태이므로 초기 상태임을 나타내는 제어 정보를 소켓의 메모리 영역에 기록하는데, 이 과정을 통해 소켓이 만들어집니다.
- 소켓이 만들어지면 소켓을 나타내는 디스크립터를 애플리케이션에 알려줍니다.(함수 값 리턴)
- 디스크립터를 받은 애플리케이션은 이후 프로토콜 스택에 데이터 송수신 동작을 의뢰할 때 디스크립터를 통지합니다.
- 디스크립터가 어느 소켓인지를 나타내면 필요한 정보는 전부 프로토콜 스택쪽에서 알 수 있기 때문입니다.
접속의 의미
- 소켓을 만들면 애플리케이션(브라우저)은 connect를 호출합니다.(위의 그림과 이어지는 내용입니다.)
- 그러면 프로토콜 스택은 자기쪽의 소켓을 서버측 소켓에 접속합니다.
- 그러나 소켓을 만든 직후에 애플리케이션에서 데이터 송신 의뢰가 오면 프로토콜 스택은 어떻게 될까요?
- 소켓을 만든 직후는 아직 거기에 아무 것도 기록되어 있지 않으므로 통신 상대가 누구인지도 모릅니다. 브라우저는 URL을 바탕으로 서버의 IP 주소를 조사하고, 포트 번호는 80번을 사용하도록 규칙으로 정해져 있으므로 필요한 정보는 있지만 아직 부족합니다.
- socket을 호출하여 소켓을 만드는 동작만으로는 프로토콜 스택에는 아무 것도 전달되지 않기 때문입니다.
- 그러므로 서버의 IP 주소나 포트 번호를 프로토콜 스택에 알리는 동작이 필요합니다.
- 서버측도 소켓이 만들어졌지만 서버측의 프로토콜 스택도 클라이언트측과 마찬가지로 소켓을 만드는 동작만으로는 통신 상대를 알 수 없습니다.
- 그래서 클라이언트에서 '이곳의 IP 주소는 xxx.xxx.xxx.xxx이고 포트 번호는 yyyy입니다. 데이터 송수신을 하고 싶은데 어떠세요?'라고 정보를 알려서 통신하려는 클라이언트가 있다는 것을 서버측에 전달합니다.
- 그러면 서버측의 프로토콜 스택도 클라이언트의 정보를 가질 수 있습니다.
- 접속 동작의 첫 번째 동작은 통신 상대와의 사이에 제어 정보를 주고받아 소켓에 필요한 정보를 기록하고 데이터 송수신이 가능한 상태로 만드는 것입니다. 여기에서 클라이언트측의 IP 주소나 포트 번호를 서버측에 알리는 것이 제어 정보 주고받기의 구체적인 예입니다.
- 데이터 송수신 동작을 실행할 때는 송수신하는 데이터를 일시적으로 저장하는 메모리 여역이 필요한데, 이 메모리 영역을 '버퍼 메모리'라고 부릅니다.
- 버퍼 메모리 확보도 접속 동작을 할 때 실행되는데, 이것이 접속(준비)한다는 동작의 의미입니다.
제어 정보를 기록한 헤더
- 위의 표의 항목들은 고정화되어 있기 때문에 접속, 송수신, 연결 끈힉의 각 단계에서 클라이언트와 서버가 대화할 때마다 거기에 이 제어 정보를 부가합니다.
- 아래 그림 같이 클라이언트와 서버 사이에 주고받는 패킷의 맨 앞부분에 부가한다는 것입니다.
- 접속 단계의 단계에서는 데이터의 송수신이 이루어지지 않기 때문에 아래 그림의 (b)와 같이 데이터가 없고 패킷의 내용은 제어 정보로만 이루어져 있습니다.
- 통신 동작에 이용하는 제어 정보는 다음의 두 종류입니다.
- 헤더에 기입되는 정보
- 소켓(프로토콜 스택의 메모리 영역)에 기록되는 정보
접속 동작
- connect(<디스크립터>, <서버측의 IP 주소와 포트 번호>, ....) (여기에서부터 시작)
- 여기에 서버측의 IP 주소와 포트 번호를 쓰면 명령이 프로토콜 스택의 TCP 담당 부분에 전달됩니다. 그러면 TCP 담당 부분은 IP 주소로 표시된 상대, 즉 서버의 TCP 담당 부분과의 사이에 제어 정보를 주고받습니다.
TCP 3-Way Handshaking
- 클라이언트는 서버에 접속을 요청하는 SYN(a) 패킷을 보냅니다.
- 서버는 클라이언트의 요청인 SYN(a)을 받고 클라이언트에게 요청을 수락한다는 ACK(a+1)와 SYN(b)가 설정된 패킷을 발송합니다.
- 클라이언트는 서버의 수락 응답인 ACK(a+1)와 SYN(b) 패킷을 받고 ACK(b+1)를 서버로 보내면 연결이 성립(establish)됩니다.