실습 목표#
- 라즈베리파이에서 데이터 손실을 발생시켜 TCP 재전송을 WireShark로 확인한다.
- 데이터가 사라진 경우와 확인 응답이 사라진 경우의 차이를 구분한다.
- 라즈베리파이에서 지연을 발생시켜 데이터 손실과 어떻게 다른지 확인한다.
실습 준비#
손실&지연 스크립트 사용법#
라즈베리파이에서 손실과 지연을 발생시키는 스크립트는 다음과 같다.
loss_on.sh, loss_off.sh : 데이터 전송 과정에서 손실 발생 및 해제
delay_on.sh, delay_off.sh : 데이터 전송 과정에서 지연 발생 및 해제
파일 실행 권한 부여 스크립트는 다음과 같다.
chmod +x loss_on.sh loss_off.sh delay_on.sh delay_off.sh
다음은 손실 스크립트 작성 예시이다. 자세한 내용은 뒤에서 다룬다.
sudo ./loss_on.sh data 50
sudo ./loss_on.sh ack 80
'loss_off.sh' 코드를 통해 걸어둔 데이터 손실 설정을 해제할 수 있다.
sudo ./loss_off.sh
손실 규칙 적용 여부#
nft 명령어를 사용하면 데이터 손실/지연 설정 여부를 확인할 수 있다.
sudo ./loss_on.sh data 50
sudo nft list table inet labloss
chain out { ... tcp sport 9999 ... drop }
실습 1. 빌드와 실행#
데이터 손실이 일어나는 것을 확인하기 위해 통신을 여러 번 수행할 것이다. 정상 동작을 먼저 확인한 후에 데이터 손실 및 지연 발생 상황과 비교한다.
make
./tcp_echo_server
'tcp_echo_client'의 첫 번째 인자는 송수신 반복 횟수를 나타낸다.
make
./tcp_echo_client 10
실습 2. 데이터 손실 재현#
이제 실제로 데이터 손실을 재현해 본다.
loss_on.sh의 첫 번째 인자 : 어떤 데이터를 손실시킬지 (예 : 이 인자가 data라면 데이터 패킷을, ack라면 확인응답(ACK)를 손실시키겠다는 의미)
loss_on.sh의 두 번째 인자 : 데이터 손실 확률 (예 : 이 인자가 50이라면 데이터 손실 확률이 50%라는 의미)
sudo ./loss_on.sh data 50
./tcp_echo_server
해당 스크립트는 데이터 패킷을 50% 확률로 손실시키겠다는 의미이다.
아래 스크립트를 입력하여 송수신 반복 횟수를 설정하고, 손실 설정을 해제할 수 있다.
./tcp_echo_client 10
sudo ./loss_off.sh
데이터 손실 분석#
각각의 이벤트가 의미하는 바는 다음과 같다. 다음 표를 참고하여 사진에 나타난 이벤트를 분석해보자.
| 이벤트 | 의미 |
|---|---|
Retransmission |
응답을 못 받아 데이터를 다시 보냄 |
Spurious Retransmission |
데이터는 이미 도착했는데 실행한 재전송 |
Dup ACK |
중복 데이터를 받은 서버가 "이미 받았다"고 재확인 |

TCP Retransmission 분석#
다음표를 참고하여 TCP Retransmission을 분석해 보자.
9a e7 27 0f dd c1 89 a7 58 b6 18 07 80 18 00 3f
cb 0f 00 00 01 01 08 0a c6 84 e7 36 4b f8 8a 75
6d 73 67 20 23 32
| 오프셋 | 바이트 | 필드 | 의미 |
|---|---|---|---|
| 0~33 | 1타임과 같은 구조 |
Ethernet + IP Header | - |
| 34 ~ 35 | 9a e7 |
Src Port | OS가 임시 할당한 Port #, 39655 |
| 36 ~ 37 | 27 0f |
Dst Port | 9999 |
| 38 ~ 41 | dd c1 89 a7 |
Seq # | 상대 번호 7, 앞서 보낸 줄과 같은 값 |
| 42 ~ 45 | 58 b6 18 07 |
Ack # | 상대 번호 7 |
| 46 | 80 |
Data Offset / Reserved | TCP Header 길이, 8 X 4 Bytes = 32 Bytes |
| 47 | 18 |
TCP Flags | PSH + ACK |
| 48 ~ 49 | 00 3f |
Window Size | 수신 버퍼 크기, 63 X 1024 = 64512 |
| 50 ~ 51 | cb 0f |
Checksum | 오류 검출용 |
| 52 ~ 53 | 00 00 |
Urgent Pointer | 긴급 데이터 위치, 미사용 |
| 54 ~ 65 | 01 01 08 0a ⋯ 8a 75 |
TCP Options | NOP · Timestamp 12 Bytes |
| 66 ~ 71 | 6d 73 67 20 23 32 |
Data | msg #2, 6 Bytes |
실습 3. 확인 응답 손실 재현#
실습 2 스크립트에서 첫 번째 인자와 두 번째 인자를 다르게 설정하여 손실을 재현한다. 실습2에서의 'data 50' 인자를 'ack 80'으로 변경한다.
sudo ./loss_on.sh ack 80
./tcp_echo_server
아래 스크립트를 입력하여 송수신 반복 횟수를 설정하고, 손실 설정을 해제할 수 있다.
./tcp_echo_client 10
sudo ./loss_off.sh
확인 응답 손실 분석#
Info 항목에서 [Event]를 확인할 수 있다. 앞에서 살펴봤던 [Retrnansmission], [Dup ACK]를 확인할 수 있다.

Dup ACK 패킷 분석#
Dup ACK 패킷은 다음 표를 참고하여 분석할 수 있다.
96 a3 27 0f 07 8d 59 3f c9 89 3d 7e 80 10 00 3f
e7 d6 00 00 01 01 08 0a 48 4b ce 23 4e a6 6e b7
| 오프셋 | 바이트 | 필드 | 의미 |
|---|---|---|---|
| 0~33 | 1타임과 같은 구조 |
Ethernet + IP Header | - |
| 34 ~ 35 | 96 a3 |
Src Port | OS가 임시 할당한 Port #, 38563 |
| 36 ~ 37 | 27 0f |
Dst Port | 9999 |
| 38 ~ 41 | 07 8d 59 3f |
Seq # | 상대 번호 63 |
| 42 ~ 45 | c9 89 3d 7e |
Ack # | 상대 번호 63 |
| 46 | 80 |
Data Offset / Reserved | TCP Header 길이, 8 X 4 Bytes = 32 Bytes |
| 47 | 10 |
TCP Flags | ACK, 데이터 없음 |
| 48 ~ 49 | 00 3f |
Window Size | 수신 버퍼 크기, 63 X 1024 = 64512 |
| 50 ~ 51 | e7 d6 |
Checksum | 오류 검출용, 줄마다 다름 |
| 52 ~ 53 | 00 00 |
Urgent Pointer | 긴급 데이터 위치, 미사용 |
| 54 ~ 65 | 01 01 08 0a ⋯ 6e b7 |
TCP Options | Timestamp만 줄마다 다름 |
실습 4. 지연 주입#
손실에 이어 이번에는 지연을 재현해 본다.
delay_on.sh 다음 인자 : 지연 시간 (단위 : ms)
sudo ./delay_on.sh 500
./tcp_echo_server
아래 스크립트를 입력하여 송수신 반복 횟수를 설정하고, 지연 설정을 해제할 수 있다.
./tcp_echo_client 10
sudo ./delay_off.sh
지연 분석#
지연은 데이터가 사라지는 것이 아니므로 재전송이 일어나지 않는다. 아래 사진에서 확인할 수 있듯이 요청과 응답 사이 시간 차가 설정한 만큼 벌어진다.

실습 5. 손실과 지연 동시에 재현#
이번에는 손실과 지연 둘 다 설정하여 결과를 분석한다. 인자의 값을 자유롭게 변경해가며 결과를 관찰한다.
sudo ./loss_on.sh data 50
sudo ./delay_on.sh 500
./tcp_echo_server
아래 스크립트를 입력하여 송수신 반복 횟수를 설정하고, 설정을 해제할 수 있다.
./tcp_echo_client 10
sudo ./loss_off.sh
sudo ./delay_off.sh