[1% network] Ch02. TCP-IP의 데이터를 전기신호로 만들어 보낸다
Ch02. TCP-IP의 데이터를 전기신호로 만들어 보낸다
학습할 것
- 소켓을 작성한다.
- 서버에 접속한다.
- 데이터를 송수신한다.
- 서버에서 연결을 끊어 소켓을 말소한다.
- IP와 이더넷의 패킷 송수신 동작
- UDP 프로토콜을 이용한 송수신 동작
소켓을 작성한다.
1. 프로토콜 스택의 내부 구성
프로토콜 스택의 내부는 역할이 다른 몇 부분으로 나뉘어져 있다.
- 네트워크 애플리케이션
- 브라우저, 웹 서버 등의 프로그램이 해당되며 여기부터 아래로 향하여 데이터 송수신 등의 일을 의뢰한다.
- Socket 라이브러리에는 리졸버가 내장되어 있다. DNS 서버에 조회하는 동작을 수행한다.
아래부터는 OS 내부를 나타낸다
- 프로토콜 스택
- 윗부분에는 TCP / UDP 프로토콜을 사용하여 데이터 송수신을 담당한다. 애플리케이션에서 보낸 의뢰를 받아 송수신 동작을 실행한다.
- IP 프로토콜을 사용하여 패킷 송수신 동작을 제어한다.
- 드라이버 소프트웨어
- LAN 드라이버는 LAN 어댑터의 하드웨어를 제어한다.
- 하드웨어
- LAN 어댑터는 실제 송수신 동작 즉 케이블에 대해 신호를 송수신하는 동작을 실행한다.
2. 소켓의 실체는 통신 제어용 제어 정보
소켓의 역할
프로토콜 스택은 내부에 제어 정보를 기록하는 메모리 영역을 가지고 있으며 여기에 통신 동작을 제어하기 위한 제어 정보를 기록한다.
ex) 통신 상대의 IP 주소와 포트 번호 통신 동작의 진행 상태
소켓은 개념적인 것이어서 실체가 없으므로 이 제어 정보를 소켓의 실체라고 생각하자
소켓에는 통신 동작을 제어하기 위한 여러가지 제어 정보가 기록되어있는데 프로토콜 스택은 이것을 참조하여 다음에 무엇을 해야 하는지 판단한다.
그러므로 프로토콜 스택이 동작하기 위한 제어 정보 제공이 소켓의 역할이라고 할 수 있다.
3. Socket을 호출했을 때의 동작
브라우저가 Socket 라이브러리 안에 있는 socket이나 connect라는 프로그램을 호출했을 때 프로토콜 스택 내부가 어떻게 동작하는지 살펴보자.
소켓 생성 과정
- 애플리케이션이 socket을 호출하여 소켓을 만들 것을 의뢰하면 프로토콜 스택은 의뢰에 따라 한 개의 소켓을 만든다.
- 이 때 프로토콜 스택은 소켓 한개 분량의 메모리 영역을 확보한다.
- 이 시점의 소켓은 아직 송수신 동작이 시작되지 않은 초기 상태이므로 제어 정보를 소켓의 메모리 영역에 기록한다. (소켓 생성)
- 소켓이 만들어지면 소켓을 나타내는 디스크립터를 애플리케이션에 알린다.
- 디스크립터를 받은 애플리케이션은 프로토콜 스택에 데이터 송수신 동작을 의뢰할 때 디스크립터를 통지한다.
서버에 접속한다.
1. 접속의 의미
- socket을 호출하여 소켓을 만드는 동작만으로는 프로토콜 스택에 아무 것도 전달되지 않기 때문에 서버의 IP 주소나 포트번호를 프로토콜에 알리는 동작이 필요하다.
- 이는 접속 동작의 한가지 역할이다.
- 서버측도 마찬가지로 소켓이 만들어졌지만 프로토콜 스택에 정보가 없어 통신 상대를 알 수 없다.
- 그래서 클라이언트 측에서 서버측에 통신 동작 개시를 전달하는 것도 접속 동작의 역할이다.
접속 동작 단계
- 통신 상대와 제어 정보를 주고 받아 소켓에 필요한 정보를 기록하고 데이터 송수신이 가능한 상태로 만드는 것.
- 클라이언트측의 IP주소나 포트 번호를 서버측에 알린다.
- 송수신하는 데이터를 일시적으로 저장하는 메모리 영역(버퍼 메모리)을 확보한다.
2. 맨 앞부분에 제어 정보를 기록한 헤더를 배치한다.
제어 정보의 종류
제어 정보는 두가지로 나뉜다.
- 이더넷이나 IP의 제어 정보
- 소켓에 기록하여 프로토콜 스택의 동작을 제어하기 위한 정보
- 애플리케이션에서 통지된 정보, 통신 상대로부터 받은 정보 기록
- 송수신 동작의 진행 상황 등도 기록되고, 프로토콜 스택은 정보를 참조하면서 동작한다.
- TCP의 제어 정보
3. 접속 동작의 실제
- 접속동작은 애플리케이션이 Socket 라이브러리의 connect를 호출하는 곳부터 시작된다
connect(<디스크립터>, <서버측의 IP주소와 포트번호>, ......)
- 접속동작의 처음은 TCP 담당 부분에서 접속을 나타내는 제어 정보를 기록한 TCP 헤더를 만드는 것이다.
- 이후 TCP 헤더의 송신처와 수신처의 포트 번호로 접속하는 소켓을 지정한다.
- 소켓을 데이터 송수신할 수 있는 상태로 만드는 방법은 아래와 같다.
- 클라이언트 -> 서버
- 접속해야하는 소켓을 지정후 컨트롤 비트인 SYN 라는 비트를 1로 만든다.
- 시퀀스 번호나 윈도우 값은 후에 설명
- 서버 -> 클라이언트
- 서버측의 TCP 담당부분이 TCP 헤더를 조사하여 수신처 포트번호에 해당하는 소켓을 찾아낸다
- 해당 소켓에 필요한 정보를 기록하고 접속 동작이라는 상태로 변경 (6장에서 자세히 설명)
- SYN 플래그 비트를 1로 만든다
- ACK 플래그 비트를 1로 만든다. - 패킷을 받은 것을 알리기 위한 동작
- 패킷을 받은 것을 알리기 위한 동작
- 클라이언트 -> 서버
- 서버로부터 받은 응답의 TCP 헤더를 조사
- 소켓에 서버의 IP 주소나 포트 번호 등과 함께 소켓에 접속완료를 나타내는 제어 정보 기록
- ACK 플래그 비트를 1로 만든 TCP 헤더를 서버에 송신
- 이후 커넥션은 close를 호출하여 연결을 끊을 수 있다.
데이터를 송수신한다.
1. 프로토콜 스택에 HTTP 리퀘스트 메시지를 넘긴다.
- connect에서 애플리케이션에 제어가 되돌아오면 데이터 송수신 동작에 들어간다.
이 동작은 애플리케이션이 write를 호출하여 프로토콜 스택에 송신데이터를 건네주는 곳부터 시작한다.
- 프로토콜 스택은 받은 데이터의 내용에 무엇이 쓰여있는지 알지 못한다
- 데이터를 곧바로 송신하지 않고 자체의 버퍼 메모리 영역에 저장하고, 다음 데이터를 기다린다
MTU와 MSS
출처 : https://garimoo.github.io/study/2018/03/26/MSS_MTU.html
- 버퍼 메모리에 저장하는 정도는 몇가지 요소를 통해 판단한다
- 한 패킷에 저장할 수 있는 데이터의 크기
- MTU : 한 패킷에 저장할 수 있는 데이터의 크기
- MSS : 헤더를 제외하고 한개의 패킷으로 운반할 수 있는 TCP의 데이터의 최대 길이
- 즉, 애플리케이션에서 받은 데이터가 MSS를 초과하거나 MSS에 가까운 길이에 이르기까지 저장하게 된다.
- 타이밍
- 애플리케이션의 송신 속도가 느릴 경우 MSS 데이터 양만큼 데이터를 저장하는데 시간이 오래걸려 송신 동작이 지연된다
- 내부의 타이머를 이용하여 일정 시간 이상 경과시 패킷을 송신한다
- 한 패킷에 저장할 수 있는 데이터의 크기
- 위와 같이 판단 요소는 두가지이나 상반된 면이 있다. 따라서 양자를 절충해서 송신 동작을 실행해야한다. 이에 대한 책임은 프로토콜 스택 개발자에게 맡겨져 있다
- 또한 애플리케이션에서 송신의 타이밍을 제어할수도 있다.
- 데이터 송신 의뢰시 옵션을 지정 가능
2. 데이터가 클 때는 분할하여 보낸다.
HTTP 리퀘스트 메시지가 MSS의 길이를 초과한 길이라면, 송신 버퍼에 들어있는 데이터를 맨 앞부터 차례대로 MSS 의 크기에 맞게 분할하고, 분할한 조각을 한 개씩 패킷에 넣어 송신한다.
3. ACK 번호를 사용하여 패킷이 도착했는지 확인한다. (3-way-handshaking)
TCP에는 송신한 패킷이 상대에게 올바르게 도착했는지 확인하고 도착하지 않았으면 다시 송신하는 기능이 있으므로 패킷을 송신한 후에는 확인 동작으로 넘어간다.
- TCP 담당 부분은 데이터를 조각으로 분할할 때 조각이 통신 개시부터 따져서 몇 번째 바이트에 해당하는지를 세어둔다.
- 데이터 조각을 송신할 때 세어둔 값을 TCP 헤더에 기록하는데 시퀀스 번호라는 항목이 이에 해당한다.
연결 동작 과정
- Client -> Server
- SYN : 클라이언트 측 초기 시퀀스 넘버인 500으로 연결 요청(SYN)을 보낸다.
- Server -> Client
- SYN + ACK : 클라이언트에게 시퀀스 넘버가 500인 연결 요청을 받고 서버 측 초기 시퀀스 넘버인 250과 다음에 받기를 기대하는 시퀀스넘버(Ack.Num)인 501로 확인 응답(ACK)과 연결 요청(SYN)을 보낸다.
- Client -> Server
- ACK : 서버에게 시퀀스 넘버가 250인 확인 응답과 연결 요청을 받고, 연결 요청에 대한 확인 응답(ACK)를 보낸다.
연결 동작 시 서버의 상태
- SYN_SENT : SYN 패킷을 보내 연결을 요청한 상태이다. 아직 연결이 된 상태는 아니다.
- SYN_RCVD : SYN 패킷을 받아 연결 요청을 받은 상태입니다. SYN+ACK 패킷을 보내 연결을 승인합니다.
- ESTABLISHED : ACK 패킷을 받아 연결이 된 상태입니다.
TCP는 이 방법으로 상대가 데이터를 받은 것을 확인한다.
그리고 확인될때 까지 송신한 패킷을 버퍼 메모리에 보관해둔다.
송신한 데이터에 대응하는 ACK 번호가 상대로부터 돌아오지 않으면 패킷을 재전송한다.
4. 패킷 평균 왕복 시간으로 ACK 번호의 대기 시간을 조정한다.
실제 오류 검출과 회복의 원리는 꽤 복잡하기 때문에 요점이 되는 부분만 설명한다. 먼저 ACK 번호가 돌아오는 것을 기다리는 시간인데 이 대기 시간을 타임아웃 값이라고 한다.
- 타임아웃 값이 짧을 시 ACK 번호가 돌아오기 전에 다시 데이터롤 보내게 된다.
- 타임아웃 값을 길게 설정할 경우 패킷을 다시 보내는 동작이 지연되어 속도 저하의 원인이 된다.
따라서 적절한 값으로 설정해야 하므로 TCP는 대기 시간을 동적으로 변경하는 방법을 취하고 있다.
- 데이터 송신 동작을 실행하고 있을 때 항상 ACK 번호가 돌아오는 시간을 계측한다.
- ACK 번호가 돌아오는 시간을 기준으로 대기시간을 판단한다.
5. 윈도우 제어 방식으로 효율적으로 ACK 번호를 관리한다.
위에서는 한 개의 패킷을 보내고 ACK 번호를 기다리는 방법을 설명하였다. 그러나 ACK 번호가 돌아올 때까지 아무 일도 하지 않고 기다리는 것은 시간 낭비이므로 윈도우 제어라는 방식에 따라 송신과 ACK 번호 통지의 동작을 실행한다.
윈도우 제어란?
- 한 개의 패킷을 보낸 후 ACK 번호를 기다리지 않고 차례대로 연속해서 복수의 패킷을 보내는 방법이다.
윈도우 제어 사용 시 주의할 점
- ACK 번호를 기다리지 않고 차례대로 패킷을 보내면 수신 측의 능력을 초과하여 패킷을 보내는 일이 발생할 수 있다.
구체적인 예시는 다음과 같다.
- 수신측은 TCP 패킷을 수신하면 버퍼 메모리에 데이터를 임시 보관한다.
- ACK 번호 계산 / 조각 연결하여 원래 데이터 복원 후 애플리케이션에 건내기 위함이다.
- 수신측에서 애플리케이션에 건네주는 속도보다 빠른 속도로 데이터가 도착하면 버퍼 메모리가 넘친다.
해결책
- 수신측에서 송신측에 수신 가능한 데이터 양을 통지한다.
TCP 헤더의 윈도우 필드
를 이용
- 수신 가능한 데이터 양의 최댓값을
윈도우 사이즈
라고 한다.
6. ACK 번호와 윈도우를 합승한다.
윈도우 통지 동작은 언제 일어날까?
윈도우 통지가 필요할 때는 수신측이 수신 버퍼에서 데이터를 추출하여 애플리케이션에 건네주었을 때이다.
(수신측에서 애플리케이션에 데이터를 건네주고 수신 버퍼의 빈 영역이 늘어났을 때)
ACK 번호는 수신측에서 받은 데이터의 정상 수신을 확인한 경우에만 송신측에 보낸다.
이 두가지를 조합해보면 수신측에서 송신측에 ACK 번호 통지와 윈도우 통지 패킷을 따로따로 보내므로 효율성이 저하된다.
해결책
수신측은 ACK 번호나 윈도우를 통지할 때 바로 보내지 않고 잠시 기다린 뒤 다음 통지 동작과 함께 보낸다.
- ACK와 윈도우 통지가 일어난 경우
- 하나의 패킷으로 묶어서 보낸다.
- ACK 통지가 연속된 경우
- 최후의 것만 통지한다.
- 윈도우 통지가 연속된 경우
- 최후의 것만 통지한다.
7.HTTP 응답 메시지를 수신한다.
- 송신측(브라우저)은 HTTP 리퀘스트 메시지를 보내면 웹 서버에서 응답 메시지가 돌아오기를 기다리고 돌아오면 수신한다.
- 이를 위해 브라우저는 read 프로그램을 호출한다.
- 프로토콜 스택이 제어권을 갖는다.
- 수신 버퍼에서 수신 데이터를 추출하여 애플리케이션에 건네준다.
- 서버에서 응답 메시지 패킷이 도착하면 확인 후 수신 버퍼에서 수신데이터를 추출하여 애플리케이션에 건네준다.
- 타이밍을 가늠하여 윈도우를 송신측에 통지한다.
서버에서 연결을 끊어 소켓을 말소한다.
1. 데이터 보내기를 완료했을 때 연결을 끊는다. (4-way-handshaking)
연결 끊기
데이터 송수신 동작이 끝난 후 프로토콜 스택의 움직임을 설명한다.
- 애플리케이션이 송신해야하는 데이터를 전부 송신했다고 판단했을 때
- 웹의 경우 : 리퀘스트메시지를 보내고 서버에서 응답 메시지를 반송하면 데이터 송수신이 끝나므로 연결끊기 단계에 들어간다.
- HTTP 1.1의 경우 서버가 응답메시지를 반송한 이후에도 클라이언트가 다음 리퀘스트 메시지를 보내는 것이 가능하므로 이 때는 클라이언트 측에서 먼저 연결 끊기 단계에 들어갈 수도 있다.
연결 끊기 동작 과정 (클라이언트 먼저 선언 시)
- Client -> Server
- FIN + ACK : 서버 측에 연결을 종료하겠다는 FIN 패킷을 보낸다.
- Server -> Client
- ACK : 클라이언트에게 받은 FIN 패킷에 대한 확인 응답(ACK)을 보낸다.
- Server -> Client
- FIN+ACK : 클라이언트에게 데이터를 마저 받은 후에 클라이언트 측에 연결을 종료하겠다는 FIN 패킷을 보낸다.
- Client -> Server
- ACK : 서버에게 받은 FIN 패킷에 대한 확인 응답(ACK)를 보내고 일정 시간 후에 종료한다.
연결 끊기 동작 시 서버의 상태
- FIN_WAIT_1 : FIN 패킷을 먼저 보내 연결 종료를 요청한 상태이다
- 상대의 확인 응답(ACK)를 기다린다.
- CLOSE_WAIT : 상대에게 FIN 패킷을 받아 연결 종료를 요청받은 상태이다.
- 확인 응답(ACK)를 보내고 나머지 데이터 수신을 기다린다.
- FIN_WAIT_2 : FIN 패킷을 보낸 후, 상대에게 확인 응답(ACK)을 받은 상태이다.
- FIN 패킷을 기다린다.
- LAST_ACK : 나머지 데이터를 모두 수신 후에 FIN 패킷을 보내 연결 종료를 요청한 상태이다.
- TIME_WAIT : FIN 패킷을 받고 이에 대한 확인 응답(ACK)를 보낸 후 일정 시간 대기하는 상태이다.
- ACK 패킷이 상대에게 전송됨을 보장하기 위해
- CLOSED : FIN 패킷에 대한 확인 응답(ACK)을 받고 종료된 상태이다.
- TIME_WAIT 상태에서도 일정 시간 후에 종료된다.
TIME_WAIT 상태가 필요한 이유
이 때 일정 시간 대기한 후에 종료하는 이유는 마지막 확인 응답(ACK)이 상대에게 전송됨을 보장하기 위해서이다.
서버가 ACK를 받지 못하면 서버는 종료를 하지 못하므로 클라이언트가 마지막 확인 응답을 보냈으나 서버측에서 못 받았을 경우 <timeout> FIN_ACK
를 다시 보낸다.
2. 소켓을 말소한다.
소켓을 바로 말소하지 않고 오동작을 막기 위해 잠시 기다린 후 소켓을 말소한다.
- 연결 끊기 단계에서 마지막에 클라이언트가 ACK 송신하는 부분에 오류가 생겼을 경우 서버는 ACK가 돌아오지 않으므로 다시 FIN을 송신하게 된다.
- 만약 클라이언트 소켓이 기다리지 않고 말소되면 기록되어 있던 제어 정보가 없어지므로 소켓에 할당되어 있던 포트 번호도 알 수 없게 된다.
- 이 시점에 다른 애플리케이션이 생성한 소켓에 같은 포트 번호가 할당이 될 수도 있는데 이 때 FIN을 받으면 그 소켓이 연결 끊기 동작에 들어갈 수도 있다.
그러므로 보통 몇 분 정도 기다린 후 소켓을 말소한다.
3. 데이터 송수신 동작을 정리한다.
IP와 이더넷의 패킷 송수신 동작
1. 패킷의 기본
TCP 담당 부분이 통신 상대와 통신할 때 IP 담당 부분에 의뢰를 한다. 이 의뢰를 받은 IP 담당 부분이 어떻게 패킷을 전송하는지 알아보자.
출처 : https://better-together.tistory.com/110
패킷의 구성
- 헤더
- 수신처를 나타내는 주소 등의 제어 정보
- 데이터
- TCP에서 보낸 TCP 헤더를 포함한 패킷
패킷 통신 기본 구조
- 패킷의 송신처가 되는 기기가 패킷을 생성한다.
- 헤더에는 적절한 제어 정보, 데이터에는 데이터가 담긴다.
- 가장 가까운 중계장치에 송신한다.
- 중계 장치는 패킷의 헤더를 조사하여 다음 목적지를 판단한다.
- 이동 작업을 반복해서 패킷을 중계하면 최종적으로 수신처의 기기에 도착한다.
이 때 TCP/IP 패킷에는 조금 더 발전하여 두 개의 헤더(MAC 헤더(이더넷용), IP 헤더(IP용))가 붙어있다.
라우터는 IP 규칙에 따라 목적지를 확인하여 패킷을 다음 라우터에 운반하고 허브는 이더넷 규칙에 따라 서브넷 안에서 패킷을 다음 라우터에 운반한다.
2. 패킷 송수신 동작의 개요
- TCP 담당부분은 데이터 조각에 TCP 헤더(IP 주소가 담긴)를 부가한 것을 IP 담당부분에 건네준다.
- IP 담당 부분은 이를 디지털 데이터로 간주하고 그 앞에 제어 정보를 기록한 IP헤더와 MAC헤더를 부가한다.
- IP 헤더 : IP 프로토콜에 규정된 규칙에 따라 패킷의 목적지가 되는 액세스 대상 서버의 IP 주소를 기록
- MAC 헤더 : 이더넷 등의 LAN을 사용하여 가장 가까운 라우터까지 패킷을 운반할 때 사용하는 제어정보를 기록 - MAC 주소
- 이렇게 생성된 패킷을 네트워크용 하드웨어 (이더넷 / 무선 LAN) LAN 어댑터에 건네준다.
송신 동작
- LAN 어댑터에 0이나 1의 비트가 이어진 디지털 데이터를 보내고, LAN 어댑터가 전기나 빛의 신호 상태로 바꾸어 케이블에 송출한다.
수신동작
- 신호 상태의 패킷을 디지털 데이터로 변환한후 IP 담당 부분에 전달한다.
3. 수신처 IP 주소를 기록한 IP 헤더를 만든다.
IP헤더의 구조
- 수신처의 IP 주소
- TCP 담당부분에서 통지된 통신상대의 IP주소를 그대로 설정한다.
- 송신처 IP 주소는 LAN 어댑터에 의해 결정된다.
- 프로토콜 번호
- 패킷에 들어간 내용물이 어디에서 의뢰받은 것인지를 나타낸다.
- TCP : 06, UDP : 17
IP 주소는 컴퓨터에 할당되는 것이 아니라 LAN 어댑터에 할당이 되므로 여러개의 LAN 어댑터를 장착하면 각 LAN 어댑터에 서로 다른 IP주소가 할당되기 때문에 LAN 어댑터가 결정되면 IP 주소가 결정된다.
4. 이더넷용 MAC 헤더를 만든다.
- 이더넷에는 TCP/IP 개념이 통용되지 않는다.
- 이더넷은 TCP/IP와 다른 구조로 패킷의 수신처를 판단하여 운반한다.
- 이더넷 수신처 판단 구조로 사용하는 것이 MAC 헤더이다.
MAC 헤더의 구조
- 수신처 MAC 주소
- 송신처 MAC 주소
- 이더 타입(Ether Type)
- 사용하는 프로토콜의 종류를 나타낸다.
- 이더넷의 내용물은 IP나 ARP라는 프로토콜 소켓이며 규칙에 따라 값을 기록한다.
5. ARP로 수신처 라우터의 MAC 주소를 조사한다.
- 이더넷에는 연결되어있는 전원에게 패킷을 전달하는 브로드캐스트라는 구조가 있다.
- 이 브로드캐스트를 이용하여 연결된 전원에게 MAC 주소를 조사하게 된다.
- 이 후 ARP 캐시 메모리에 조사한 값을 저장한다.(몇 분정도만)
이렇게 만들어진 MAC 헤더를 IP 헤더 앞에 붙이면 패킷이 완성된다.
6. 이더넷의 기본
이더넷은 다수의 컴퓨터가 여러 상대와 자유롭게 적은 비용으로 통신하기 위해 고안된 통신 기술이다.
- MAC 헤더의 수신처 MAC 주소에 기록된 상대에게 패킷을 전달한다.
- 송신처 MAC 주소에 따라 누가 송신한 것인지 알 수 있다.
- 이더 타입에 의해 패킷의 내용물을 나타낸다.
7. IP 패킷을 전기나 빛의 신호로 변환하여 송신한다.
- LAN 어댑터가 디지털 데이터(IP가 만든 패킷)를 전기나 빛의 신호로 변환하여 네트워크 케이블에 송출한다.
LAN 어댑터를 제어하기 위해 LAN 드라이버 소프트웨어가 필요하다.
- LAN 어댑터 사용을 위해 초기화 작업이 필요하다.
- 이더넷의 송∙수신 동작을 제어하는 MAC이라는 회로에 MAC주소를 설정하는 것이다.
- LAN 어댑터의 ROM를 제조시 MAC주소 기록하므로 이것을 읽어와서 MAC 회로에 설정하는 것이다.
8. 패킷에 3개의 제어용 데이터를 추가한다.
이더넷 헤더
출처 : https://velog.io/@ash3767/%EC%9D%B4%EB%8D%94%EB%84%B7-%ED%94%84%EB%A0%88%EC%9E%84-%EA%B5%AC%EC%A1%B0
- LAN 드라이버는 IP 담당부분에서 패킷을 받으면 그것을 LAN 어댑터의 버퍼 메모리에 복사한 뒤 MAC 회로에 명령을 보내어 MAC 회로 작업을 시작한다.
- MAC 회로는 송신 패킷에 3가지 데이터를 부가한다.
- 프리 앰블 (Preamble)
- 송신하는 패킷을 읽을 타이밍을 잡기 위한 것
- 1과 0으로 나타내는 비트열이다.
- 스타트 프레임 딜리미터 (SFD)
- 패킷의 시작을 나타내는 표시
- 프레임 체크 시퀀스 (FCS)
- 패킷을 운반하는 도중에 잡음 등의 영향으로 파형이 흐트러질 수 있는데 이 오류를 검출하기 위한 비트열이다.
- 프리 앰블 (Preamble)
9.허브를 향해 패킷을 송신한다.
- 위와 같이 제어용 데이터를 추가하면 케이블에 송출하는 패킷이 완성된다.
- 송신 동작은 리피터 허브를 사용하는 반이중 모드와 스위칭 허브를 사용하는 전이중 모드가 있다.
반이중 모드 동작 과정
- 케이블에 다른기기가 송신한 신호가 흐르는지 조사 후 신호가 흐르지 않으면 송신을 시작한다.
- MAC 회로가 패킷 전체를 1비트 씩 전기 신호로 변환한다.
- PHY 또는 MAU 회로가 케이블에 송출하는 형식으로 변환하여 케이블에 송신한다. -송신 뿐만 아니라 수신 신호선에서 신호가 들어오는지를 감시한다.
신호 도중 수신 신호가 들어오면?
- 송신 동작을 중지하고 충돌 사실을 다른 기기에 알린다 (재밍 신호)
- 대기시간을 계산하여, 그 대기시간 만큼 기다린후 재전송
- 다시 충돌시 대기 시간을 2배로 늘려 반복
- 열 번째 시도후 해결되지 않으면 오류로 판단
10. 돌아온 패킷을 받는다.
- 반이중 동작의 이더넷에서는 리피터 허브에 접속된 케이블 전체에 신호를 흘러 보낸다
반이중 모드의 수신 과정
- 프리앰블부터 읽으며 파형에서 타이밍을 계산한다.
- 스타트 프레임 딜리미터가 나오면 다음 비트부터는 디지털 데이터로 변환하여 읽는다.
- PHY회로에서 MAC 회로로 보낸다
- MAC회로에서 FCS 값을 검사한다.
- 패킷의 마지막에 같이 보내진 FCS를 비교하여 일치 여부 판별 -> 오류시 폐기
- MAC 헤더의 수신처 MAC 주소를 조사 -> 자신에게 온 게 아닐 경우 폐기
- 본체에 통지
인터럽트 구조 사용
컴퓨터 본체의 작업에 끼어들어, LAN 어댑터를 확인하도록 주의를 주는 것)
- LAN 드라이버가 LAN 어댑터의 버퍼 메모리에서 수신한 패킷 추출
- MAC 헤더의 프로토콜 판별
- 프로토콜에 맞는 프로토콜 스택에 건네준다
11.서버의 응답 패킷을 IP에서 TCP로 넘긴다.
- LAN 드라이버는 TCP/IP 의 프로토콜 스택에 패킷을 건넨다
- IP 담당 부분은 IP 헤더 부분을 조사하여 포멧에 문제가 없는지 확인하고 수신처의 IP 주소를 조사한다
- 자신의 IP가 아니라면 ICMP 메시지로 상대에게 오류 통지
- 패킷을 원래의 모습으로 조립한다 (리어셈블링)
- 이후 TCP 담당부분에 건네준다
- TCP 담당 부분은 관련 소켓을 찾는다.
- 소켓은 다시 적절한 동작을 하여, 애플리케이션에게 데이터를 주거나, 접속, 연결 끊기 등 동작을 실행한다.
UDP 프로토콜을 이용한 송수신 동작
- TCP와 UDP는 TCP/IP의 전송계층에서 사용되는 프로토콜이다. 전송 계층은 IP에 전달되는 패킷의 오류를 검사하고 재전송 요구 등의 제어를 담당하는 계층이다.
1. 수정 송신이 필요없는 데이터의 송신은 UDP가 효율적이다.
TCP 와 UDP
- 두 프로토콜은 모두 패킷을 한 컴퓨터에서 다른 컴퓨터로 전달해주는 IP 프로토콜을 기반으로 구현되어 있지만 서로 다른 특징을 가지고 있다.
- 신뢰성이 요구되는 애플리케이션에서는 TCP를 사용하고 간단한 데이터를 빠른 속도로 전송하고자 하는 애프리케이션에서는 UDP를 사용한다.
2. 제어용 짧은 데이터
- DNS 서버에 대한 조회 등 제어용으로 실행하는 정보 교환은 한 개의 패킷으로 끝나는 경우가 많다
- 만약 오류 발생시 응답이 돌아오지 않으므로 다시 데이터를 요청하면 된다
3. 음성 및 동영상 데이터
- 음성이나 영상 데이터는 결정된 시간안에 데이터를 건네주어야 한다
- TCP의 경우 시간이 더 걸리므로 재생 타이밍이 맞지 않을 수 있다.