[Network] TCP / IP 통신 시 일어나는 일
들어가면서
명색이 웹 개발자인데 막상 클라이언트와 서버 통신 시 어떤 과정으로 데이터를 전달하는지 제대로 알지 못했다.
전체적인 플로우는 해당 영상을 참고하면서 공부했다.
TCP / IP 연결 플로우
상황: 클라이언트에서 서버 측 Springboot 애플리케이션으로 TCP / IP 연결을 수립하려고 한다.
- 클라이언트 측에서 서버와 TCP / IP 통신을 시도한다.
- 상대 애플리케이션의 포트번호, 내 포트번호로 (TCP Header) 세그먼트를 만든다. 이때 3 way handshake를 시작한다면 세그먼트에 SYN를 켜서 보낸다.
- IP 계층에서 상대 서버 컴퓨터의 IP와, 내 컴퓨터의 IP를 포함하여 (IP Header) 세그먼트를 패킷으로 포장한다.
- 패킷이 랜카드 드라이버에서 수신, 발신 MAC 주소, EtherType을 (Ethernet Header) 붙여 Frame로 포장된다.
- 랜카드에서 전기 신호로 바뀌어 서버로 날아간다. 이 과정에서 여러 라우터를 거친다.
- 서버 컴퓨터의 랜카드에서 전기 신호가 Frame으로 변경된다.
- Frame이 ip 계층에서 우리의 ip가 맞는지 확인 후 세그먼트로 언팩된다.
- 해당 요청이 SYN라면, OS(kernel mode) 레벨에서 세그먼트에 ACK + SYN를 세팅하여 다시 클라이언트로 전송한다.
- 클라이언트에서 ACK + SYN를 받는다면 최종적으로 ACK를 세팅해 서버로 전송한다.
- 서버에서 ACK를 받으면 신뢰할 수 있는 연결이라고 판단한 후, 해당 연결에 해당하는 소켓을 하나 만들어 통신을 이어간다.
용어 정리
TCP (Transmission Control Protocol, 전송 제어 프로토콜)
애플리케이션 사이에서 안전하게 데이터를 통신하는 규약이다.
속도를 조금 포기하는 대신, 데이터를 완전한 형태로 안전하게 주고받을 수 있게 한다.
3 way handshake
TCP가 안전하게 데이터를 전송할 수 있는 연결 방식. 통신에 필요한 데이터들을 교환하고 동기화한다.
- 연결 수립 순서
- 클라이언트가 TCP 헤더에 SYN를 켜서 서버에 전달한다.
- 서버가 받은 TCP 헤더에 SYN이 켜져있다면, 수신한 뒤 ACK + SYN을 함께 켜서 반환한다.
- 클라이언트가 받은 TCP 헤더에 ACK + SYN이 켜져있다면, ACK를 켜서 다시 서버에 보낸다.
- 서버에서는 해당 TCP 연결이 안전하다고 판단하고 소켓을 할당해 통신을 시작한다.
- 교환하는 정보
- 초기 순서번호(ISN): 내 데이터는 N번부터 시작할테니, 너가 잘 받았으면 다음엔 N+1번을 요구해.
- 수신 기본 윈도우 크기: 한 번에 N kb 이상의 데이터를 보내면 수신 버퍼에 여유 공간이 없으니, 이거 이상 보내지 마.
- 최대 세그먼트 크기 (SSM): 세그먼트 하나가 N byte 이상이면 IP 계층에서 찢어지니, 해당 사이즈 이하로 보내.
IP (Internet Protocol, 인터넷 프로토콜)
패킷을 통해 지정한 IP주소로 최대한 빠르게 데이터를 전송할 수 있는 규약이다.
패킷은 데이터의 순서를 신경쓰지도 않고, 데이터가 누락됐을 때, 재전송 할 수 있는 규칙도 없다.
TCP / IP 통신
TCP의 순서를 보장하고 데이터 누락 시, 데이터를 재전송해 안전하게 데이터를 전송하는 특징과, IP의 빠른 데이터 전송 특징을 합쳐, 안전하고 빠르게 데이터를 전송할 수 있는 TCP / IP 통신을 사용한다.
소켓
TCP / IP 계층을 추상화한 계층. 애플리케이션이 파일 입출력을 하듯, 네트워크 통신을 할 수 있도록 제공하는 커널 레벨의 인터페이스, 메모리 버퍼.
소켓은 TCP / IP 연결마다 하나씩 생성되고, OS는 각 소켓을 4가지 정보의 조합으로 식별한다.
- Local IP: 서버의 IP
- Local Port: 서버의 포트
- Remote IP: 클라이언트의 IP
- Remote Port: 클라이언트의 포트
이 4가지 조합은 항상 유일하기 때문에 항상 원하는 곳으로 데이터를 전송할 수 있다.
TCP Segment
데이터를 주고받을 때, 하나의 데이터를 한 번에 보내지 않고 잘게 쪼개서 주고받는다.
이때, 작은 조각을들 Segment라고 하며 Segment는 Header와 Data로 이루어져 있다.
- Header
Header에는 발신 프로그램의 port, 수신 프로그램의 port, 다음에 받아야 할 Segment 순서를 포함하고 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source Port | Destination Port |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Sequence Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Acknowledgment Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Data | |U|A|P|R|S|F| |
| Offset| Reserved |R|C|S|S|Y|I| Window |
| | |G|K|H|T|N|N| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Checksum | Urgent Pointer |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Options | Padding |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| data |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Packet
만들어진 TCP Segment를 IP 계층에서 패킷이라는 단위로 포장한다. 패킷은 세그먼트와 유사하게 3가지 구조로 되어있으며, 각각 Header, Payload, Trailer로 구성되어 있다.
- Header
수신 서버의 IP, 발신 서버의 IP, 네트워크 프로토콜, 번호가 들어있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Version| Traffic Class | Flow Label |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Payload Length | Next Header | Hop Limit |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
+ +
| |
+ Source Address +
| |
+ +
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
+ +
| |
+ Destination Address +
| |
+ +
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- Payload
수신자가 요청한 데이터이다. 위에서 말한 TCP Segment 전체가 Payload가 된다.
프레임
IP 계층에서 패킷이 만들어지면, 물리적인 인프라를 통해 다음 장비로 실어 보내기 위해 Frame으로 캡슐화한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
+-------+-------+-------+-------+-------+-------+-------+-------+
| | | | | | | | |
| Preamble (7 octets) & SFD (1 octet) | -> 하드웨어 동기화 신호
| | | | | | | | |
+-------+-------+-------+-------+-------+-------+-------+-------+
| | | | | | |
| Destination MAC Address (6 octets) | -> 목적지 MAC (앞표지 1)
| | | | | | |
+-------+-------+-------+-------+-------+-------+
| | | | | | |
| Source MAC Address (6 octets) | -> 출발지 MAC (앞표지 2)
| | | | | | |
+-------+-------+-------+-------+-------+-------+
| | |
| Type (2 oct) | -> EtherType (예: IPv4는 0x0800) (앞표지 3)
| | |
+-------+-------+-------+-------+-------+-------+-------+-------+
| |
: Payload (IP Packet) (46 ~ 1500 octets) : -> 알맹이 (여기에 IP 패킷이 들어감)
| |
+-------+-------+-------+-------+-------+-------+-------+-------+
| | | | |
| Frame Check Sequence (FCS) | -> Trailer
| (4 octets) |
| | | | |
+-------+-------+-------+-------+
- Header
MAC주소: 다음 하드웨어 목적지인 MAC 주소가 붙어있다.
EtherType: Payload에 실린 데이터가 어떤 프로토콜인지(IPv4, IPv6 등등)인지 명시한다.
- FCS
오류 검출용 필드

