[Network] TCP (1) : Connection과 Handshake, 그리고 TCP Error Control
전송 계층 (Transport Layer)
- 프로토콜 : TCP (Transmission Control Protocol), UDP (User Datagram Protocol)
- 양 끝 노드의 프로세스-프로세스간의 논리적 통신 제공, 네트워크 계층에서 설정한 경로로 하나의 프로세스에서 다른 프로세스로 전송한다. 효율적 데이터 전송, 데이터의 신뢰성 검사
- Network layer은 호스트 간의 통신 및 문제 해결, Transport layer은 프로세스 간의 통신 및 문제 해결
Segment
Transport Layer에서의 데이터 단위, 메시지의 조각
왼쪽에서 TCP data가 가질 수 있는 최대 byte = 1460byte
- 총 1500 byte 중, TCP header, IP Header가 20byte씩 차지
Segment size = 1480byte.
Max Segment Size = 1460byte
위 두 단어는 뜻과 계산이 일치하지 않아 보인다. 즉 용어의 문제이다. 용어를 정할 때 이렇게 계산하기로 합의된 사항이다.
- 발신자 : 데이터를 세그먼트(Segment)로 분할하고, 각 세그먼트에 대한 헤더를 추가하여 목적지까지 전송한다. 넘버링을 해준다(순서가 바뀜을 방지한다)
- 수신자 : 모든 세그먼트가 다 도착 할 때까지 기다리며, 받은 세그먼트를 다시 합치고, 데이터의 무결성을 확인하여 손상된 세그먼트를 복구한다.
TCP(Connection-oriented Transport Layer Protocol)
UDP vs TCP
UDP가 Connectionless임에 반해 TCP는 Connection-Oriented, 즉 통신을 시작하기 전에 논리적인 연결을 설정한다. 이와 동시에 데이터를 전송할 때, 오류 검출 및 복구 메커니즘이 있다. 따라서 TCP는 신뢰성 전송이 필요한 애플리케이션, 즉 웹 브라우저, 이메일, 파일 전송 등에서 사용되며, UDP는 실시간 통신이나 속도가 중요한 게임, 동영상 스트리밍 서비스 등에서 사용된다.
https://sjh9708.tistory.com/192
TCP의 특성
1. Reliable : 무오류성. 신뢰성, 아래는 무오류성을 보장하기 위해 TCP에 적용한 기술들이다.
- Checksum : 패래티 코드와 같이 오류 검출
- Acknowledge : 잘 받았다는 피드백 메시지
- Timer : Acknowledge를 적절한 시간에 보내기 위한 타이머
- Sequence Number : Segment, 즉 메시지의 순서 유지를 위함
- Pipelining : Segment 여러 개를 쭉쭉 보낸다. 그리고 한꺼번에(마지막 Segment를 받고) ACK를 보낸다.
2. Resent : 재전송을 통해 에러 제어
3. Delivers data in order sent : 순서 유지
4. Point to point : 한명의 Sender, 한명의 Receiver
5. Full duplex data :양쪽 방향으로 데이터를 전달할 수 있는 프로토콜
6. Connection-oriented : UDP와 달리 반드시 서버와 connection을 맺고 통신(Handshake)한다. 신뢰성 있는 전송을 위해서이다.
7. Congestion control : 만약 패킷의 전송 속도보다 빠른 속도로 패킷이 입력되고 대기 행렬이 쌓이게 되면 패킷 지연 시간이 기하급수적으로 증가하므로 이를 통제한다.
8. Flow control : 메시지 통신의 흐름 제어
TCP 헤더의 구조
Acknowledge number : 잘 받은 Segment들이 몇 번 까지 인지를 나타낸다. 즉 다음번에 들어올 것으로 기대되는 Segment의 Sequence number(Cumulative ACK : 누적된 ACK)
HLEN : TCP segment의 길이를 정의, option head의 끝을 알린다.
Checksum : 오류 검출을 위한 비트
ACK : 이것이 Acknowledge임을 알려주는 Flag(Segment가 전 순서의 Segment의 Acknowledge number과 일치함을 알려주는 Flag), 잘 받았다는 응답. 수신자 입장에서 오류가 있을 시 Acknowledge를 안 보내는 것이 오류 대처법
PSH : 데이터를 모아서 보내지 않고 모아지지 않았지만 빨리 보내야할 때 알려주는 Flag(Segment가 잘 모이지 않을 경우)
Sequence number : 세그먼트 데이터의 첫 번째 바이트의 Number를 표시. 데이터 유실시 몇 번째 Segment가 사라졌는지 알 수 있다. -> 1000바이트의 segment들을 보낸다고 가정하면 첫 번째 segment의 seq=1, 두 번째 segment의 seq=1001
Application과 TCP 사이의 구조
Connection : 보내는 자와 받는 자와의 약속. 자원을 저장할 수 있는 버퍼. 링크의 Bandwidth 등을 약속한다.
왼쪽은 Sender, 오른쪽은 Receiver, Buffer는 Linked List로 구동.
Sender : 어플리케이션에 맞게 데이터를 생성하여 TCP에 Byte 단위로 던져준다.
버퍼의 한 칸이 바이트 단위로 저장됨. 바이트를 모아 Segment 단위로 데이터가 축적된 후 데이터가 나가게 된다.
그림에서 파란 부분 : 전송이 이미 된 부분도 버퍼에 남아 있다. Receiver가 정상적으로 데이터를 받지 못 했을 때를 대비.
Receiver : 어플리케이션이 버퍼의 분홍색 맨 위쪽부터 쭉쭉 데이터를 수신받는다.
Segment 일련번호가 순서대로 오지 않았을 경우 : Buffer을 적당히 비워 두고 나중에 채워준다. -> Segment의 길이를 알아야 한다.
(Out of order segment : 3번이 먼저 들와야 하는데 4번이 먼저 들어온 경우 버퍼를 비워 놓았다가 3번이 오면 다 같이 올려 보내는 방식.)
TCP의 Connection 방식
Connection : 서로 상대를 확인을 하고 데이터 전송을 시작하자 약속을 맺는 것. UDP와 다른 점이다. TCP에서는 보통 3-way Handshake 방식을 사용하여 Connection을 맺는다.
2-way Handshake
2-way Handshake는 통신의 무결성이나, 흐름 제어 및 혼잡 제어를 처리하기 위한 메커니즘으로 적절하지 않아 다른 연결 설정방식을 사용하는 편이다.
- req_connection : 클라이언트가 서버에게 연결을 설정하고자 요청을 보낸다. 요청 패킷에는 클라이언트가 사용할 수 있는 정보(포트 번호, 초기화 정보 등)가 포함된다.
- acc_connection : 서버는 클라이언트의 요청을 받으면 연결을 수락하고, 클라이언트에게 응답을 보낸다
- data : Connection이 완료되면 데이터를 전송한다.
3-way Handshake
Connection
- SYN(Sequence Number) 요청: 클라이언트가 서버에게 연결을 설정하고자 SYN 패킷을 보낸다.
클라이언트가 초기화할 수 있는 무작위의 시퀀스 번호가 포함되어 있다. 이를 통해 클라이언트는 서버에게 통신을 시작하고자 한다는 신호를 보낸다. SYN 비트(SYNbit)가 설정되면 시퀀스 번호(Seq)를 시작으로 연결 설정을 위한 통신이 시작된다. - SYN-ACK 응답: 서버는 클라이언트로부터 SYN 패킷을 받으면, 클라이언트의 요청을 받아들이고 응답하기 위해 SYN-ACK 패킷을 보낸다.
패킷에는 서버가 클라이언트의 SYN을 수락했음을 알리는 ACK(확인)와 무작위의 시퀀스 번호가 있다. ACK 비트가 설정되면 ACK 번호(ACKnum)이 수신된 데이터 중 마지막으로 수신한 바이트의 다음 바이트를 가리키게 된다. - ACK 응답: 클라이언트가 서버로부터의 SYN-ACK 패킷을 받으면, 서버의 응답을 수락하기 위해 ACK 패킷을 보낸다. 서버로부터의 SYN-ACK를 수락했음을 알리는 역할을 한다.
Connection close
서버는 수동적이다. Connection을 맺자고 하는 것도 클라이언트, 끊자고 하는 것도 클라이언트이다.
Connection을 종료시킬 때, Client는 Finish flag를 Set해서 보내고 서버는 그 즉시 ACK를 보낸다.
근데 사실 서버는 보낼 데이터가 남아있을 수 있다.. 즉 ACK 를 보냇지만 더 줄게 있는 상황이다. -> 진짜 서버가 다 데이터를 보내면 FIN flag를 보내서 관계 청산을 하고 클라이언트가 ACK를 보내게 된다.
Time wait후에 자원(버퍼)를 해제한다 ->서버의 데이터가 Delay에 의해서 지연 되는 것을 조금 기다리는 용도이다.
ARQ(Automatic Request, 자동 재전송 요구)
TCP와 관계없이 독립적으로 발전한 기술. 노드와 노드 간의 일대일 전송.
신뢰성 있는 데이터 전송을 보장하기 위해 사용되는 기술이며. 데이터 전송 중에 발생하는 오류를 감지하고 복구할 수 있다.
Stop-and-Wait ARQ
Sn : 다음번에 저장할 공간
Rn : 다음번에 프레임이 들어오면 저장할 공간
Transmission delay : frame(segment)전송을 시작된 시점과 전송을 완료한 시간
Propagation delay : sender에서 receiver까지 전송되는 시간
- 데이터 전송: 송신자는 데이터를 패킷으로 나누어 전송한다. 패킷에는 시퀀스 번호가 있다.
- 대기: 송신자는 데이터를 전송한 후, ACK를 기다린다.
- ACK 수신: 수신자는 패킷을 받으면 이를 확인하고, 정상적으로 수신되었다는 ACK를 전송한다. 이 ACK에는 수신된 데이터의 시퀀스 번호가 있다.
- 재전송: ACK를 받지 못한 송신자는 타임아웃이 발생하거나 ACK에 문제가 있을 경우에는 해당 데이터를 재전송한다.
- 다음 데이터 전송: 송신자는 ACK를 받은 후 다음 데이터를 전송해야 한다.
Frame 전송에 에러가 발생하는 경우 : Receiver가 ACK 를 보내지 않는다. Sender은 적당한 시간을 기다렸다가 ACK가 와야 할 시간이 되었는데 안 오면 오류가 발생한 것으로 상정하고 Frame을 재전송한다(Timer 이용)
Frame 말고 ACK 전송에 에러가 발생하는 경우 : Frame을 정상적으로 보냇다고 쳐도 ACK가 정상적으로 오지 않았기에 Frame 재전송.
근데 여기서 문제점은 Receiver은 재전송된 패킷과 아까 패킷이 서로 다른 패킷이라고 생각한다. 그래서 application message가 똑같은 것이 두 번 간다. 이런 경우 오류 발생할 수 있다.
- 해결방법 : Frame에 일련번호(ID)를 붙인다. 이걸로 통해서 같은 패킷임을 인지하여 재전송 패킷임을알 수 있다.
- ID는 몇 개를 사용해야 할까? : 2개면 된다. 위에서 ACK 전송에 오류가 난 경우에서 0번이 두 번 오면 ACK가 깨졋다는 사실을 인지할 수 있다. 두 번째 패킷은 자연스럽게 폐기되었다.
Go-Back-N ARQ
Stop-and-Wait ARQ와 달리 송신자가 여러 개의 패킷을 연속적으로 전송할 수 있다. 송신자가 일정한 윈도우 크기(window size) 내에서 여러 개의 패킷을 전송하고, 수신자는 연속적인 ACK를 통해 여러 개의 패킷을 한꺼번에 확인할 수 있다.
다음 상황은 Frame 1,2,3을 거의 동시에(굉장히 빠른 시간 안에) ACK를 받지 않고 보내는 상황이다.또한 Frame1의 ACK가 깨지고 Frame2, Frame3 ACK 잘 받았다.
재전송 여부 판단 : Frame1을 재전송을 해야 하나? 안 해도 된다. ACK3이 왔으니까 앞의 패킷을 잘 받았다는 의미이다. 설사 ACK2가 깨졌어도 커버가 가능하다.
Window : 동시에 받을 수 있는 패킷의 사이즈. 위 그림의 리스트에서 까만 부분이 Window 크기이다. 해당 크기 만큼의 Frame을 동시에 받을 수 있으며, 만약 송신자가 윈도우 크기 내에서 수신자로부터 확인을 받으면, 송신자는 윈도우 크기를 유동적으로 조정할 수 있다.
Sn(next point to write) : 다음 번에 저장할 공간. Stop-and-wait와 다른 점은 ACK를 받지 않았어도 증가시킨다. 윈도우 상황을 보면 Sender의 상황파악 가능.
Go back n 의 단점
Go-Back-N은 현재 윈도우 내의 제대로 수신된 패킷만을 기록한다. 이에 의해 발생하는 문제로 수신자가 오류가 발생한 패킷에 대한 정보를 유지하지 못한다는 것을 뜻한다.
따라서 윈도우 내에서 오류가 발생하면, 오류가 발생한 패킷부터 다시 전송되어야 한다. 이로 인해 이전에 이미 성공적으로 전송된 패킷들도 다시 전송되어야 하므로, 오버헤드가 크다.
Frame2가 오류가 발생 했다고 가정하자. Frame3은 일단 보낸다. 근데 Frame 3을 보내도 receiver는 ACK를 보내지 않는다.
(Rn=2일 때 Frame2가 도착하지 않았으므로 Rn2를 증가시키지 않고 ACK를 보내지 않는다. Rn=2인데 Frame3을 보내면 ACK를 보내지 않음.)
그러면 2번부터 다시 재전송하고 3번을 재전송한다. 이래야 receive pointer가 제대로 작동한다.
그래서 Go back-n은 잘 사용하지 않는다. 위의 경우는 Go-back-2라고 칭한다.(2번으로 go back한다는 의미)
TCP Error Control
TCP의 오류 제어 기능은 신뢰성 있는 데이터 전송을 보장하기 위한 메커니즘이다.
Go-back N과 비슷한점
1. 패킷 유실 확인을 타임아웃에 의존
2. ACK가 오지 않은 최초의 패킷부터 시작해서 연속으로 재전송한다.
Go-back N과 다른 점
1. Out-of-order segment : 순서가 뒤바뀌어서 들어온 segment에서 누락된 패킷이 들어올 때 까지 Hold한다.
2. Sequence number를 사용하여 순서를 관리한다.
3. Window : Go-back-N에서는 송신자가 윈도우 크기를 결정한다. 그에 반해 TCP는 Sender와 Receiver가 각각의 윈도우 크기를 사용한다. 이를 다양한 사이즈. 적절한 사이즈로 조절하는게 TCP 의 핵심이다.
Out-of-order 상황
TCP는 순서가 바뀌어서 도착한 패킷을 처리할 수 있다.
누락된 패킷이 도착할 때까지 해당 패킷을 유지하고 처리를 지연시킨다.
RTT(Round trip time) : 세그먼트를 보내고 ACK가 도착하는데 걸리는 시간, TCP의 경우 계산하기에 복잡하다.
이 Timeout period는 생각보다 길 수 있고 이것을 매번 기다리는것이 비효율적일수도 있다.
-> 이거를 개선하기 위한 방법 (NAK 사용없이) : Duplicate ACK
3-duplicated ACK
수신자가 패킷을 받았지만 패킷이 손실되었다고 판단할 때, 재전송을 요청하기 위해 중복된 ACK를 보내며, 송신자에게 패킷이 손실되었음을 알려주는 신호로 사용된다.
순서가 바뀌어서 온 Segment에 대해서, 3번 연속으로 기대하지 않은 Segment가 도착하지 않으면 계속 ACK를 301로 보낸다.
한 개씩 보내면 비효율적이다. 타임아웃이 라운드 트립 타임보다 더 길게
설정되기 때문이다.
연속으로 세그먼트를 보내게 되면 시간차가 거의나지
않고 Sender가 오류가 발생 했다고 상정 할수있다.
Wireshark로 살펴보는 TCP
Connection : 3-way Handshake
클라이언트 컴퓨터와 gaia.cs.umass.edu 사이의 TCP 연결을 하는 과정을 살펴보자.
가장 처음의 SYN flag가 포함된 segment를 조사하였다. Sequence number은 0이었고 포함되어 있는 SYN flag로 SYN segment를 식별 가능하다.
Gaia서버가 Client에게 Reply 해준 SYNACK Segment를 조사하였다.
Sequence number은 relative로 0이었고 포함되어 있는 SYN flag와 ACK flag로 SYNACK segment를 식별 가능하다.
3-way handshake 과정이므로 클라이언트가 SYN을 전달했으므로 그에 대한 답변인 ACK를 포함한다. 즉 전송한 SYN 번호 + 1을 ACK로 전송한다.
Acknowledgment numbe은 다음 패킷의 sequence number로 기대되는 1이다.
다음은 HTTP에서 POST명령을 포함하고 있는, 3-way handshake 이후의 첫 data를 포함하고 있는 Segment이다. 이 Packet의 Sequence number은 1이다.
시퀀스 번호 확인과 각각의 세그먼트 발송 시간 확인
다음은 HTTP에서 POST명령 이후의 6개의 Segment이다.
클라이언트가 서버에 보낸 Data의 Sequence number은 reply하는 ack 번호와 같은 것을 통해서 보낸 Segment에 대한 reply 패킷을 조사할 수 있었고 이를 통해서 Segment를 받은 시간을 알 수 있었다.
각각의 Segment의 Sequence number은 1,505,1865,3425,4885,6345였다.
세그먼트가 전송된 시점과 해당 확인 응답이 수신된 시점 사이의 차이를 감안할 때의 세그먼트 각각에 대한 RTT 값 확인
RTT value는 Segment가 전달되는 시간을 의미한다. 서버가 클라이언트에게 ACK를 보내는 패킷을 통해서 이 값을 확인할 수 있다. 6개의 Segment들은 2개의 ACK를 받을 수 있었는데 각각의 RTT를 segment 안에서 확인 가능했다.
첫번째 ACK는 326번 segment에 대한 응답, 두번째 ACK는 327,328,329번, 세번째 ack에서 330,331번에 대한 응답을 포함한다.
Window size 확인
각각 6개의 segment의 length는 504,1460,1460,1460,1460,1460이다
할당되는 버퍼 사이즈, 즉 Window size는 계속해서 증가하는 추세이다
첫번째 ACK는 504byte의 data를 포함하고, 두번째 ACK는 4380byte의 data를 포함하고 세번째 ACK는 8760byte의 data를 포함한다.
앞에서 Window size가 점점 증가하는 것을 확인할 수 있었는데 이에 따라 한 번에 보내는 Segment의 양이 증가하고, 그에 따른 ACK의 data가 증가하는 것을 확인했다.
다음의 경우에는 수신자가 다음의 ACK가 어떤 segment에 대한 ACK임을 식별하는 방법은 Sequence number과 Acknowledge number을 비교함 으로서 알 수 있다. 다음의 경우는 각각의 Segment에 대한 각각의 ACK를 일단 보류하고 일정 수의 Segment들을 묶어서 Ack를 보내는 것을 알 수 있다.
References
Data Communications and Networks, 4th Edition, Forouzan, McGraw-Hill
'CS > 운영체제 & 네트워크' 카테고리의 다른 글
[Network] TCP (2) : TCP Flow Control, Congestion Control (흐름 제어와 혼잡 제어) (3) | 2024.03.05 |
---|---|
[Network] Transport Layer : UDP (0) | 2024.03.03 |
[Network] NAT : 공인 IP와 사설 IP (+ 포트 포워딩 설정) (0) | 2024.02.24 |
[Network] Network Layer : IP & DHCP & ICMP (0) | 2024.02.23 |
[Network] 네트워크 주소 체계(Port, MAC, IP Address)와 DNS (0) | 2024.02.23 |