이 글은 성공과 실패를 결정하는 1%의 네트워크 원리 책(이도희 역)을 기반으로 재구성한 것입니다.
application은 OS의 protocol stack에 request message를 보내달라고 한다. server와 client는 다음 과정을 통해 연결된다.
1. server가 socket을 만들고 대기한다.
2. client가 socket을 만든다.
3. client가 server의 socket에 연결한다.
4. client와 server가 socket을 통해 데이터를 주고받는다.
5. socket 연결을 끊는다.
이전 포스팅에서 웹 브라우저가 request message를 작성하고 OS에게 송신을 맡긴다고 했다. 이 글에서는 OS의 protocol stack과 LAN driver가 어떻게 message를 송신하는지 살펴본다. TCP, UDP, IP, ethernet, LAN adapter를 위주로 살펴본다.
keywords : TCP, UDP, IP, LAN adapter, ethernet, socket, protocol stack, IP address, port, packet, IP header, MAC header, LAN driver, MAC address, ethernet
application이 request message를 작성하면 위 그림과 같은 순서로 작업한다.
- application이 request message를 작성한다.
- socket library의 resolver가 DNS server에 request message를 날리고 목적지 IP address를 얻어온다. - 이전 포스팅에서 여기까지 작성했다.
- OS의 TCP나 UDP를 사용해 data를 송/수신하고, IP를 사용해 packet 송/수신을 제어한다.
- ICMP는 Internet Control Message Protocol의 약자로 packet 운반 시 오류를 알려준다.
- ARP는 Address Resolution Protocol로 IP address로 MAC address를 얻어온다.
- LAN driver가 LAN adapter를 제어하고, LAN adapter는 케이블을 통해 신호를 송/수신한다.
Socket
ip = gethostbyname("hyeile.tistory.com");
socket_desciptor = socket(); // ... socket 생성
connect(socket_desciptor, ip:port, ...); // 접속
write(socket_descriptor, ...); // 송신
result = read(socket_descriptor, ...): // 수신
close(socket_descriptor); // 연결 끊기
지난 게시글에서 위와 같이 socket을 만들고, 연결하고, 데이터를 주고 받고, 연결을 끊는다고 했다. 이 때 IP address와 port가 필요하다고 했고. 여기에 추가로 데이터 교환이 어떻게 진행되는지 알기 위한 추가적인 정보가 socket library에 들어 있으며, OS의 protocol stack은 항상 socket의 내용을 보면서 작업을 진행한다.
TCP, Transmission Control Protocol
TCP 연결의 전체 과정은 위 그림과 같다.
socket 생성 이후 application이 connect()를 호출해 server socket에 접속하고 data를 주고받는다. 이 때 socket 생성 직후에는 초기화된 상태이기 때문에 socket 생성만으로는 connect할 수 없다. 때문에 server IP address, port를 protocol stack에 알려야 한다. 이는 server socket도 마찬가지로 어떤 client가 자신에게 접속하고 싶어하는지에 대한 정보가 없다. 따라서 connect시에는 client와 server가 서로의 정보를 교환하는 것이 제일 먼저가 된다. 이 과정이 접속 동작이다.
이후 서로 데이터를 주고 받는다. 송/수신 동작이다.
마지막으로 연결 끊기 동작을 한다. 앞에서 언급했듯 서로가 연결을 끊는 것을 확인하면 연결을 끊는다.
접속 동작
application이 connect()를 호출하면 OS의 protocol stack으로 control flow가 넘어가며, 내부적으로 다음과 같은 로직을 실행한다. 핵심적인 내용인 굵은 글씨만 보면 된다. 참고로 이 과정은 3 way handshake라고도 한다.
- client가 server에게 "내 정보는 ~~이고, 너와 연결하고 싶다"는 내용을 담은 TCP header를 보낸다.
- client가 TCP header를 작성한다. port, SYN bit를 1로, sequence, window값을 작성한다.
- TCP header를 client IP에게 넘긴다. client IP는 이 정보를 server에게 발송한다.
- server는 정보를 받고 확인한다. 이후 client에게 "확인했다. 내 정보는 ~~이다. 우리 연결하자."는 내용을 담은 TCP header를 보낸다.
- server IP가 이 정보를 받아 server TCP에게 넘긴다.
- server TCP가 TCP header를 분석해 port에 해당하는 socket을 찾고, client IP address나 port 등 필요한 정보를 socket에 작성한다.
- server가 TCP header를 작성한다. port, SYN bit를 1로, ACK bit를 1로, sequence, window값을 작성한다.
- server TCP가 server IP에게 TCP header를 넘기고, server IP는 client 에게 이 정보를 발송한다.
- client는 정보를 받고 확인한다. 이후 server에게 "확인했다."는 내용을 담은 TCP header를 보낸다.
- client IP가 이 정보를 받아 client TCP에게 넘긴다.
- client TCP가 TCP header를 분석해 SYN bit를 확인한다. 1인 경우 접속 성공이므로 server IP address, port 등 필요한 정보를 socket에 작성한다.
- 새로운 TCP header를 작성한다. ACK bit를 1로 만든다.
- client TCP가 client IP에게 TCP header를 넘기고, client IP는 이 정보를 server에게 발송한다.
- server는 정보를 받고 확인한다.
- server IP가 이 정보를 받아 server TCP에게 넘긴다.
- server TCP가 TCP header를 분석해 ACK bit가 1인지 확인한다.
ACK bit는 수신측이 보낸 data를 올바르게 받았다는 것을 의미한다.
이 과정을 모두 거치면 server와 client가 연결된 상태가 되고 session이 만들어진다.
TCP header
TCP header에는 다음과 같은 내용이 들어가며, client와 server는 이 정보를 사용해 서로의 상태를 확인한다. data의 앞부분에 TCP header를 붙인다.
이름 | bit | 설명 |
송/수신처 포트 번호 | 16 | port 번호 |
sequence 번호 | 32 | 이 data가 전체 data 중 몇 번째 byte부터 시작하는지 |
ack 번호 | 32 | 몇 byte까지 수신했는지 |
data offset | 4 | header size |
control bit | 6 | URG, ACK, PSH, RST, SYN, FIN 6개가 있다. ACK : data가 올바르게 수신했다는 것을 의미한다. SYN : 서로 접속을 위해 사용하는 bit이다. FIN : 연결을 끊기 위해 사용하는 bit이다. |
window | 16 | 수신측이 송신측에게 [보낼 수 있는 data size]를 보낸다. |
checksum | 16 | error check를 위해 사용한다. |
urgent pointer | 16 | 빨리 처리해야 하는 data 위치를 나타낸다. |
sequence, window
3 way handshake에서 송/수신한 sequence와 window는 바로 다음 단계에서 살펴볼 것이다.
데이터 송/수신 동작
connect()가 끝나 client와 server의 session이 형성되면 application은 write()를 호출해 data를 server에게 보낸다.
MSS와 MTU
protocol stack은 data에 관여하지 않기 때문에 application이 보낸 data만 받는다. 이 때 application의 상황에 따라 한 번에 많은 정보가 protocol stack으로 들어올 수도 있고, 여러 개 쪼개어져 들어올 수도 있다. 너무 적은 데이터를 자주 보내면 작은 packet이 많이 보내지고, 쌓일 때까지 기다리면 대기 시간이 발생한다. 이를 최적화하기 위해 protocol stack은 application으로부터 받은 data를 송신 buffer에 잠시 담고, 내부적인 최적화를 거쳐 발송한다.
이 최적화는 MSS와 timer를 기준으로 판단한다.
- MSS는 Maximum Segment Size의 약자로 한 번의 packet으로 옮길 수 있는 data의 최대 길이를 의미한다. buffer에 쌓인 data size가 MSS를 초과할 때 보내면 작은 packet을 여러 번 보낼 걱정을 하지 않아도 된다.
- buffer에 쌓인 data size가 MSS에 가까워질 때까지 기다리면 너무 오래 기다릴 수도 있다. 때문에 내부에 timer를 하나 두어 timeout이 될 때 전송한다.
이 둘은 tradeoff에 있다. MSS에 더 높은 weight를 주면 네트워크 효율이 높아지지만 느려진다. 반면 timer에 더 높은 weight를 주면 빠르지만 네트워크 효율이 나빠진다. 이 설정은 기본적으로 protocol stack이 결정하지만 application 개발자가 설정할 수도 있다.
data 분할
data가 너무 크면 분할해서 앞에서부터 MSS까지 크기를 조절하고 나눈다. 이 때 조각별로 하나의 packet이 되기 때문에 각각의 조각에 TCP header를 붙인다.
송/수신 동작
송/수신 동작은 아래와 같이 이루어진다.
- 송신측은 필요 시 data를 분할한다.
- 기존에 가지고 있던 sequence 값을 사용해 해당 data가 어디부터 시작하는지 sequence값을 TCP header에 담아 보낸다.
- 수신측 자신이 어디까지 받았는지에 대한 ACK 값을 TCP header에 담아 보낸다.
data가 작은 경우 하나의 packet을 담아 보내지만 너무 큰 경우 여러 개의 packet으로 나누어 사용한다. 송신 측에서는 어디까지 보냈는지 식별하기 위해 sequence를 사용하고 수신 측에서는 어디까지 받았는지 식별하기 위해 ack를 사용한다.
3 way handshake 과정에서 난수로 설정한 sequence 값의 초기값을 보냈다. 송신측은 이 값을 사용해 packet을 송신할 때 앞에서부터 몇 byte인지 셀 수 있으며, TCP header에 sequence 값을 설정해 어디까지 보냈는지 알린다.
위 예시에서 sequence값의 초기값은 s이다. packet은 1460byte 단위로 나누었다. 따라서 첫 조각의 sequence 값은 s+1, 두 번째 조각의 sequence 값은 s + 1461, 세 번째 조각의 sequence 값은 s + 2921이다.
이후 수신측은 송신측이 보낸 packet을 받고 data를 확인한다. 이후 자신이 어디까지 받았는지에 대한 ack 번호를 TCP header에 담아 보낸다.
위 예시에서 1460byte까지 받은 상태에서 sequence가 1461인 packet이 도착하면 누락이 없다는 것을 알 수 있다.
반면 sequence가 1461인 packet을 받지 못했는데 sequence가 2921인 packet이 도착하면 누락되었다는 것을 알 수 있다.
TCP에서 data 흐름은 server와 client가 쌍방향이다. 만약 client → server가 아니라 server → client인 경우에는 이 순서를 반대로 하면 된다.
data를 보냈을 때, ACK가 돌아올 때까지 송신한 packet을 송신 buffer에 보관한다. 만약 ACK 번호가 다시 오지 않으면 수신측에서 해당 data를 받지 못했다고 판단하고 해당 packet을 다시 보낸다. 때문에 오류가 발생해도 recover이 쉽다.
이 때 TCP가 모든 검증 과정을 거치기 때문에 application, LAN, buffer, router는 오직 보내기만 한다. 단 packet을 보내도 네트워크 자체의 문제로 인해 응답이 없는 경우 session을 강제종료한다.
Recover 방법
ACK가 돌아오지 않았을 때 문제가 발생하는 것이므로 ACK가 돌아오지 않는 것을 찾기 위해 timeout을 이용한다. timer의 일정 시간이 지나면 문제가 발생했다고 판단하는 구조이다.
이 때, ACK가 돌아올 때까지는 시간이 걸린다. 만약 네트워크가 혼잡할 경우에는 packet 송/수신에 시간이 오래 걸린다. 이 상황에서 ACK가 돌아오지 않았으니 다시 packet을 보내버리면 네트워크가 더 혼잡해진다. 때문에 어느 정도의 지연을 예상해 적당한 시간을 잡고 ACK timeout을 잡아야 한다.
네트워크의 혼잡도는 시간에 따라 계속 변하기 때문에 상수값으로 잡는 것은 좋지 않다. 때문에 ACK가 돌아오는 시간을 판단하고 동적으로 바꾸는 방식을 취한다. 빨리 돌아오면 timeout 시간을 줄이고, 느리게 돌아오면 timeout 시간을 늘린다.
window
송신측이 하나의 packet을 보내고 수신측이 ACK를 넘길 때까지 기다린 후에 다음 packet을 보내는 방식은 직관적이고 이해하기 쉽지만 비효율적이다. 때문에 송신측은 ACK를 받든말든 일단 계속 보내는 방식으로 낭비를 줄인다.
수신측에서는 받은 data를 buffer에 저장하는데, 이 때 송신측이 계속 보내기만 하면 수신 buffer가 넘칠 수 있다. (이 경우 보낸 data가 사라지거나 buffer overflow 등 문제가 발생한다) 이러한 경우를 막기 위해 window를 사용한다.
window는 수신측의 buffer size를 의미하며, 3 way handshake에서 window값을 미리 알렸다. 송신측은 이 정보를 알고 있기 때문에 data가 수신 buffer에서 넘치지 않게 계산해서 보낼 수 있다. 그리고 수신측은 buffer에 여유가 생기면 window가 바뀌었다는 내용을 TCP로 보낸다.
최적화 : window + ACK
window는 buffer에 여유 공간이 생겼을 때 보내고, ACK는 정상적으로 수신했을 때 보낸다. 지금까지 살핀 바로는 송신측에서 보낸 data가 도착하고, 수신측이 정상적으로 받았을 때 ACK를 보낸다. 잠시 후 해당 data를 수신측의 application에 넘기면 수신 buffer가 비고 이 때 window를 수신측에게 알린다.
그러나 이렇게 2번 보내면 네트워크를 2배로 사용하기 때문에, 2개를 한 번에 묶어서 보내는 것이 효율적이다. 따라서 ACK나 window를 알려야 할 때 바로 보내지 않고 잠시 대기한다. 기다릴 때 다음 동작이 발생하면 둘을 하나의 packet에 합쳐 보낸다.
이 때 ACK가 여러개라도 마지막 것만 보내면 그 앞까지는 모두 받았다는 의미가 되므로 그 앞의 것들은 보내지 않아도 된다. window도 마찬가지로 window 값이 여러개라도 마지막에 보낸 window값이 유효한 값이므로 이 값만 보내면 된다.
연결 끊기 동작
close()를 호출하면 session을 끊는 과정에 들어간다. 이 과정을 4 way handshake라고도 한다. 끊는 과정은 client가 먼저 하든 server가 먼저 하든 상관 없다. 위 그림은 여기서는 server가 먼저 끊는다는 것을 보여주며, client가 먼저 끊는 과정은 거꾸로 하면 된다.
- 송신측이 수신측에게 FIN bit를 1로 만든 TCP header를 보낸다.
- 수신측이 송신측에게 ACK를 담은 TCP header를 보낸다.
- 수신측이 송신측에게 FIN bit를 1로 만든 TCP header를 보낸다.
- 송신측이 수신측에게 ACK를 담은 TCP header를 보낸다.
이 과정이 끝나면 session이 사라져 client와 server의 연결이 끊어진다. 이 때, 바로 socket을 없애는 것이 아니라 잠시 기다렸다가 없앤다. 예를 들어 다음 경우를 보자. 이러한 경우 때문에 보통 socket은 몇분간 기다리다가 말소한다.
socket을 바로 삭제했다고 가정하고, 이 때 4번 과정에서 네트워크 지연이 발생해 수신측이 ACK를 받지 못했다고 하자. 수신측은 자신이 보낸 3번 packet에서 문제가 생겼으리라 생각하고 다시 한 번 FIN bit를 1로 설정한 TCP header를 보낸다.
그러나 이 때 송신측은 이미 ACK를 보낸 상태였고 socket이 삭제된 후 똑같은 port로 다른 session이 만들어진 상태였다. 어떻게 되겠는가? 새로운 session에서 FIN bit가 1로 설정된 TCP header가 왔으므로 해당 연결을 말소하려 할 것이다.
정리
- create()로 socket을 만들고 connect()를 호출하면 접속 동작이 실행된다.
- client가 SYN bit를 1로 만들고, sequence 초기값과 window값을 TCP header에 담아 server에게 보낸다.
- server는 SYN bit를 1로 만들고 sequence 초기값과 window값, ACK를 TCP header에 담아 client로 보낸다.
- client가 ACK를 server로 보낸다.
- session이 생성되면 data 송/수신 동작이 실행된다.
- client TCP는 data를 분할하고 sequence 번호와 data를 TCP header에 담아 server로 보낸다.
- server는 받은 data를 분석해 ACK 번호와 server window를 TCP header에 담아 client로 보낸다.
- server → client는 그 역순이다.
- 연결 끊기 동작이 수행된다. web의 경우 server가 먼저 close()를 호출한다.
- server가 FIN bit를 1로 만들고 TCP header에 담아 client로 보낸다.
- client는 ACK 번호를 TCP header에 담아 server로 보낸다.
- client는 FIN bit를 1로 만들고 TCP header에 담아 server로 보낸다.
- server가 ACK 번호를 TCP header에 담아 client로 보낸다.
UDP, User Datagram Protocol
TCP는 data를 안전하게 보내기 위해 ACK를 사용하는 data 검수를 거친다. 만약 data를 한 번에 전부 보내는 경우, 조금이라도 오류가 생기면 전체를 다시 보내야 하기 때문에 recover의 효율을 위해 packet을 나눠 보낸다.
그러나 data가 충분히 작아 하나의 packet에 들어가면 어떨까? packet이 사라졌어도 이것만 다시 보내면 된다. data를 보낼 때는 송신측에서 이것을 보내면 수신측에서 간단한 응답만으로 수신 여부를 확인할 수 있기 때문에 3 way handshake나 4 way handshake를 사용할 필요가 없어진다.
이것을 적용한 것이 UDP이다.
UDP를 사용할 때는 UDP header만 붙이고 보내기만 한다.
packet을 받을 때는 IP header에 있는 송/수신처 IP address, UDP header에 있는 송/수신처 port만 보고 해당 port에 data를 주기만 한다. protocol stack은 packet이 없어져도 무시한다. application이 그 사실을 알아차리고 data를 다시 한 번 요청하는 식으로 recover한다.
이처럼 다시 보낼 필요가 없거나 다시 보내도 쓸모가 없으면 UDP를 사용하는 것이 효율적이다. DNS server request 등 간단한 정보는 하나의 packet만 사용하므로 UDP를 쓴다. 또한 음성이나 동영상 재생에도 사용한다. 빠른 재생을 위해 사용하며 data가 사라지는 문제가 발생해도 사용자 입장에서는 잠시 멈출 뿐인, 허용할 수 있는 불편이기 때문이다.
UDP header
이름 | bit | 설명 |
송/수신처 포트 번호 | 16 | |
data 길이 | 16 | data의 길이 |
checksum | 16 | error check를 위해 사용한다. |
TCP vs UDP
TCP | UDP |
연결형(연결이 성공해야 통신 가능) | 비연결형 프로토콜(연결 없이 통신 가능) |
전송 순서 보장 | 전송 순서 보장 X |
수신 여부 확인 | 수신 여부 확인 X |
1:1 통신 | 1:1, 1:n, n:m 통신 (다대다) |
신뢰성 높음 (문제 발생 시 재전송) | 신뢰성 낮음 (재전송 X) |
느림 | 빠름 |
IP
TCP 다음 control flow는 IP이다. IP는 받은 data에 IP header와 MAC header를 붙이고 LAN adatper로 전달한다.
IP header
IP header는 IP protocol의 규칙에 따라 목적지까지 packet을 전달할 때 사용하는 정보이다. 크게 아래 2가지만 챙기면 된다.
- 송/수신처 IP address가 있으며, 수신처 IP address는 TCP에서 받은 값을 넣는다. 만약 IP address가 잘못되어 있더라도 그대로 넣는다. 송신처 IP address는 LAN adapter를 판단해 설정한다.
- IP와 router는 routing table을 보고 보낸다. (이는 다음 포스팅에서 좀 더 상세히 설명한다.)
- protocol 종류도 작성한다.
- 이외에도 여러 정보가 있다.
MAC header
MAC header는 ethernet 등의 LAN을 이용해 router까지 packet을 운반할 때 사용하는 정보이다. xx:xx:xx:xx:xx:xx처럼 총 48byte로 표기하고 8byte씩 :나 -를 사용해 분리하며, ethernet 전송을 위해 필요하다. 크게 아래와 같은 정보가 있다.
- 송/수신처 MAC address
- 송신처 MAC address : LAN adapter address
- 수신처 MAC address : 상대방의 MAC address를 적는다. 처음 시점에서는 누구에게 줄지 모르기 때문에 누구에게 줄지 알아보는 과정을 거치며, routing table의 gateway에 해당하는 정보를 작성한다.
- MAC address는 전 세계적으로 일원화해 관리한다.
- ethertype : protocol type을 의미한다. IP, ARP, IPv6 등이 있다.
ARP, Address Resolution Protocol
ARP는 MAC address를 조사하는 과정이다. MAC address를 모르기 때문에, IP address를 사용해 MAC address를 얻어오는 이 과정이 꼭 필요하다.
크게는, 하나의 subnet에 router가 broadcast를 날려 MAC address를 받는다. 만약 같은 subnet 안에 상대가 있다면 MAC address를 알 수 있다.
이 때 packet 량을 줄이기 위해 APR cache도 있다. 따라서 탐색 전 미리 ARP cache를 보고, 있으면 그 값을 가져오고 없으면 조사한다. cache는 시간이 지나면 invalid해질 수 있기 때문에 시간이 지나면 삭제한다.
IP가 MAC까지 담당하는 이유는 LAN adapter가 전송만 담당하게 하기 위함이다.
LAN adapter
LAN adatper는 아래와 같이 구성되어 있다.
신호 변환 및 송신
신호를 변환하고 송신하는 것은 LAN adapter (network interface)가 수행한다.
수행이 일어나는 과정은 다음과 같다.
- LAN adapter가 IP로부터 정보를 받으면 buffer memory에 잠시 복사한다.
- 이후 packet을 송신하게 MAC 회로에 명령을 보낸다.
- MAC 회로는 packet 앞에 [preamble과 start frame delimiter]를, 뒤에는 [frame check sequence]를 붙인다.
- preamble은 1010이 56bit 이어진 형태로, 해당 패킷의 읽을 타이밍을 결정한다.
- start frame delimiter : 10101011$_2$. 끝에서 11로 파형이 변하며 여기서부터 packet의 시작이라는 것을 알린다.
- preamble과 start frame delimiter는 총 64bit의 1010...1011인데, 끝의 11 bit를 통해 거기서부터 header의 시작이라는 것을 알 수 있다.
- 전류는 0과 1이 반복되기 때문에 어디가 0이고 어디가 1인지를 잡기 어려운데, 이를 해결하기 위해 bit 구분을 위한 clock 신호와 기존 data를 XOR 연산을 하고 이 결과를 보낸다. clock cycle은 미리 정해진 값을 사용한다. 합친 결과에서 clock을 빼면 기존 data가 나온다.
- clock cycle과 합쳐진 신호와 preamble을 사용해 어디부터 시작인지 알 수 있다.
- FCS : frame check sequence. 오류 검출용 data이다.
- MAC 회로가 PHY(MAU)로 신호 송신를 송신한다. 이 때 hub의 종류에 따라 동작 방식이 다르다. hub 종류는 바로 아래 챕터에 작성했다.
- 반이중 : repeater hub에서 사용하는 방식이다. 다른 기기가 송신한 신호가 있는지 보고, 있으면 끝까지 기다리며 다른 기기의 송신 신호가 없을 때 송신을 시작한다. 이 때 만약 다른 신호가 있는 상태에서 또 신호를 보내면 충돌난다. 만약 송신 중에 수신받으면 collision이 발생하기 때문에, 잠시 신호를 멈추라는 jamming signal을 흘린 후 시간을 바꾸어서 다시 대기한다. 이 때 대기 시간은 난수를 생성하고 기다린다. 만약 ethernet 혼잡 등으로 인해 충돌이 계속 발생하면 대기 시간을 2배로 늘려 기다리고, n번 다시 보냈는데도 해결되지 않으면 오류라 판단하고 중단한다.
- 전이중 : routing hub에서 사용하는 방식. 송/수신을 동시에 수행하며 충돌이 일어나지 않기 때문에 신호를 보내기만 하면 된다.
- PHY(MAU)는 전기 신호로 바꾼 정보를 cable에 송출한다.
- PHY(MAU) 회로가 변환 케이블에 송신한다.
ethernet은 오류가 잘 나지 않기 때문에 수신했는지 확인하지 않는다.
신호 수신
송신의 역순으로 진행한다.
- preamble, start fame delimiter를 추출하고, frame check sequence로 값을 계산 후 만약 잘못된 값이라면 폐기한다.
- MAC address 조사 후 자신에게 온 것을 처리한다.
- 자신에게 온 것인 경우 CPU에 interrupt를 보낸다. LAN의 각 buffer에서 값을 빼내면 MAC header type에 따라 적합한 protocol stack에 보낸다.
- IP protocol에서 packet이 분할된 경우라면 합친다.
- TCP가 TCP header를 확인한다. 수신처 IP와 자신의 address가 다르면 ICMP라는 신호를 줘서 오류를 통지한다.
LAN adapter는 누구에게 온 것이든 신경쓰지 않고 protocol stack에 건네기만 한다.
ethernet
ethernet은 네트워크를 구현하는 방식 중 하나로, 기본형은 크게 3가지 방식이 있다. 실체는 cable이며 cable 내에 전기 신호가 왔다갔다하는 것이다.
- 제일 기본 형태는 cable로 연결된 형태이다. 신호를 주면 연결된 모두에게 가는 형태이며 각 client는 자신에게 온 신호가 아니면 폐기한다. 이 때 자신에게 온 신호인지 판단하기 위해 MAC address를 사용한다.
- cable이 twist pair cable로 바뀌고 tranceiver cable이 repeater hub로 바뀐 형태이다. 안정성이 조금 더 올라갔다.
- 여기서 조금 더 발전한 것이 현재의 ethernet이다. switching hub를 사용해 모두에게 정보가 가는 것이 아니라 hub 내의 ethernet table을 보고 특정 client에게만 신호를 보낸다.
Packet 운반 과정
지금까지 IP가 IP header/MAC header를 붙이고, LAN adatper가 신호를 송출하는 과정을 봤다. 이렇게 신호로 바뀐 packet이 어떻게 이동하는지 보자. 좀 더 자세히는 다음 포스팅에서 설명할 예정이다.
IP는 packet 송출만 하며 운반은 hub와 router가 한다. TCP는 송/수신을 위한 확인 단계를 거치지만 IP의 경우 송/수신 모두 동일한 단계로 이루어진다.
- 송신처가 packet을 만들고 hub로 보낸다.
- IP header의 수신처는 서버 S로 고정이다. IP는 이를 바탕으로 다음으로 전달할 router를 결정한다.
- MAC header는 packet의 중계에 의해 바꿔 써진다.
- 위 그림에서 client는 hub에게 [router R1에 도착하도록] 의뢰한다. 그러면 hub는 R1으로 packet을 보낸다.
- hub가 packet을 받고 ethernet table을 참고해 MAC address에 해당하는 router에게 packet을 준다. (subnet 내의 ethernet이 중계 장치까지 packet을 운반한다.)
- router가 목적지를 확인하고 IP table을 참고해 다음 router로 보낸다. (IP가 목적지를 확인해 다음 IP의 중계 장치를 나타낸다.)
- 위 그림에서 R1 router는 어느 router로 보내면 좋을지 결정하고 MAC address를 갱신한다.
- 이를 반복한다.
- 위 그림에서 R1에서 hub를 거쳐 다음 router R2로 도착하고, 이를 반복해 server로 도착한다.
잘못된 내용이나 오탈자에 대한 지적, 질문 등은 언제나 환영합니다.
'CS > Network' 카테고리의 다른 글
[Network] 1%의 네트워크 - 5. Firewall, Proxy, Load Balance (0) | 2023.07.24 |
---|---|
[Network] 1%의 네트워크 - 4. 인터넷 내부 (0) | 2023.07.24 |
[Network] 1%의 네트워크 - 3. Cable, Hub, Router (1) | 2023.07.21 |
[Network] 1%의 네트워크 - 1. 웹 브라우저가 하는 일 (0) | 2023.07.19 |
[Network] 1%의 네트워크 - 0. 서론 (0) | 2023.07.19 |