티스토리 뷰
Why TCP?
Q. 전송 계층에는 UDP, TCP 두개의 대표적인 프로토콜을 사용하는데 왜 나누고 어떤 경우에 TCP를 사용할까?
A. UDP는 빠른 데이터 송/수신을 위해서, TCP는 Reliable한 통신을 하기 위해서 사용한다.
Mechanism for Reliable Data Transfer
Sequence Number
- 패킷의 순서를 정렬하기 위한 용도로 사용한다.
- 송신자에서 수신자로 흘러가는 패킷에 숫자를 매기는 용도이다.
CheckSum
- 전송되는 패킷 데이터 bit의 오류를 검증하기 위해 사용한다.
- Error Detect 용도, FEC & CRC를 이용해서 에러를 찾고, 메꾸고, 유효성 검사를 한다.
Acknowledgement
- 송신측에서 보낸 패킷을 수신측이 제대로 받은 경우 응답을 위해 사용한다.
- 제대로 받지 못한 경우에 응답하는 방법은 Negative Acknowledgement (NACK)이다.
Timer
- 송신측에서 보낸 패킷의 응답을 기다릴 때 사용하는 타이머이다.
- Timer는 패킷을 보내는 순간 같이 시작되며 타이머가 만료되면 패킷을 재전송하거나 커넥션을 닫는 등 적절한 조치를 취한다.
TCP 프로토콜의 특징
1. Point to point
- 송신/수신 측이 명확하게 정해져있다.
- 일반적으로 서버-클라이언트 구조로 통신이 이뤄진다.
2. Full duplex data
- 하나의 커넥션으로 양방향 통신이 이뤄진다.
- 양쪽이 송/수신 둘다 한다.
3. Reliable, in-order byte stream
- 믿을만하고, 순서가 지키져지는 byte stream으로 이뤄진다.
- 일련의 byte를 세그먼트 단위로 통신한다.
- bit를 보고 error control이 이뤄진다.
4. (receiver) Flow controlled
- 수신측 패킷 상황을 보고 window size를 적절히 조절하여 보낸다.
- 패킷이 너무 몰려서 패킷 유실이 발생하지 않도록한다.
5. (network) Congestion controlled
- 네트워크의 상황을 보고 window size를 적절히 조절하여 패킷 유실이 발생하지 않도록 한다.
- 네트워크 상황 계기판이 있는 것도 아닌데 어떻게 확인할까?
-> 암시적으로 판단한다. 패킷유실이 일정 수치 이상으로 발생하다거나, 네트워크가 너무 느리게 간다거나 등
6. Connection-Oriented
- 3-way handshake를 통해 연결지향 통신을 한다.
- 연결 지향은 BUFFER를 이용하여 이뤄진다. 데이터를 송/수신 하기 전에 송/수신 용 Buffer를 먼저 할당한다.
Flow Control, Error Control
- 데이터 재전송은 ARQ(Automatic Repeat Request)를 통해 이뤄진다.
- Error Check(Checksum, CRC)를 통해 에러를 발견하고 재전송을 요청한다. -> Reliable한 통신으로 만든다.
- Flow Control은 ACK의 수신여부로 결정된다. 보낸 패킷의 응답이 오지 않는다면 수신측 or Network의 문제로 판단하고 window size를 조절하게 된다.
- ACK는 패킷을 받을 때마다 보내지 않고 Cumulative한 방식으로 보내거나, Piggybacking 방식으로 보낸다.
- Cumulative (누적방식) : 수신된 세그먼트의 누적 결과에 대해 ACK를 보낸다. 하나하나 보내지 않고 세그먼트 여러개에 대한 누적 결과에 대해 응답함
만약 수신/송신 데이터의 양이 1:1이 아니라면 ACK만 쌩으로 보내야할 수 있는데 이를 방지하고자 사용된다. - PiggyBacking : 전송할 데이터 패킷에 Ack를 포함해서 같이 보내는 방식이다. (돼지 위에 얹힘)
- Cumulative (누적방식) : 수신된 세그먼트의 누적 결과에 대해 ACK를 보낸다. 하나하나 보내지 않고 세그먼트 여러개에 대한 누적 결과에 대해 응답함
TCP Segment 구조
TCP Header
- SRC port number, DST port number (4계층 주소 port number)
- Sequence number
- 보낼 데이터의 시작 byte 주소로 지정된다.
- Segment의 번호랑은 다르다.
- 3-way handshake를 위한 세그먼트의 경우 SEQ는 0 ~ (2^31 - 1) 사이의 랜덤값이 초기값으로 설정된다. (상대적 0을 의미)
- Acknowledgement number
- 받은 데이터의 응답값으로 다음에 받을 data의 시작 byte주소로 지정된다.
-> 받은 데이터의 seq num + data 길이 - 3-way handshake를 위한 세그먼트의 경우 ACK는 SEQ + 1로 설정된다.
- 받은 데이터의 응답값으로 다음에 받을 data의 시작 byte주소로 지정된다.
- HLEN : 세그먼트 패킷의 Header 길이이다.
- Reserved : 예약된 공간, 즉 아직 안쓰는 공간이다.
- URG, ACK, PSH, RST, SYN, FIN (특정 기능을 표시하는 1 bit들이다)
- urgent, ack, push, reset, synchronize, finish
- Window Size : Flow Control, Congestion Control을 위한 Window size
- Check sum : 에러 Detection을 위한 체크섬 비트
- Urgent Pointer : 위에 URG 비트가 켜지면 사용되는 용도이다.
6개 비트 설명
SYN
- Connection을 initiate할 때 사용한다.
ACK
- 수신 데이터의 응답 ACK의 유효성을 표시해준다. 유효하면 1
FIN
- 연결을 종료할때 사용한다.
RST
- 에러가 발생하면 연결을 중단하고 재수립한다.
PSH
- 전송받은 Host가 데이터들을 Application으로 올리라는 용도로 사용한다.
- 버퍼에 쌓아둔 데이터를 빨리 읽어들여서 상위 계층으로 올리라는 것이다.
- 해당 애플리케이션이 OS상에서 후순위로 밀려서 일을 천천히 하고 있을 때 전송이 느려질 경우 사용될 수 있다.
- 전달받은 데이터를 Application 계층으로 올려 보내기전에 버퍼가 가득찰 때까지 모으고 올라가는 것을 방지한다.
URG, URG Pointer
- 현재 사용하지 않는다. -> TCP의 in-order 정책에 어긋나는 기능이기 때문
- URG pointer는 보내는 세그먼트의 데이터의 0번 byte부터 ~ 특정 byte까지 긴급하다고 알리는 역활을 한다.
- urg pointer가 5라면 0~5byte는 긴급 byte로 버퍼에 쌓여있는 byte를 무시하고 처리하도록 한다.
TCP Connection
2-way handshake의 문제점
- 클라이언트가 Connection 요청을 보내고 서버가 응답을 한다. 이때 서버가 요청을 보고 buffer를 세팅하여 연결을 수립하고 응답 패킷을 보냈을 때 해당 패킷이 손실되면 클라이언트는 서버가 응답을 보내지 않았다고 판단하고 Timer가 만료되면 다시 연결요청을 재전송하게 된다. 서버는 수립한 커넥션을 둔 채 또 새로운 커넥션을 만들게 된다. -> 자원낭비를 유발한다.
3-way handshake 해결책
- 서버가 응답을 보내면 클라이언트가 서버의 응답을 확인하고 커넥션을 수립하고, 다시 응답을 보낸다. 서버는 자신이 보낸 응답에 대한 응답을 받고 커넥션을 수립한다.
연결수립을 위한 3-way handshake 예시
클라이언트 -> 서버 (SYN Bit = 1)
- 클라이언트 -> 서버로 처음 연결을 시작할 때 SYN (synchronize) bit를 활성화한다.
- client측 initial 패킷은 ACK가 없고 따라서 Ack Bit도 비활성화 되어있다. 이후 모든 패킷의 ACK bit는 활성화된다.
(그림 오류, A는 없는게 맞다) - SEQ number 는 0 ~ 2^32 -1 사이의 랜덤 수로 설정한다. (해당 수가 상대적 0번이 된다, 보내는 데이터의 시작 주소의 기준)
서버 -> 클라이언트 (SYN Bit = 1, ACK Bit = 1)
- 서버 -> 클라이언트로 처음 연결을 시작할 때 SYN (synchronize) bit를 활성화한다.
- 클라이언트에서 보낸 패킷의 응답으로 ACK number는 받은 패킷의 SEQ number + 1을 ACK로 설정하여 보낸다.
- SEQ number 는 0 ~ 2^32 -1 사이의 랜덤 수로 설정한다. (해당 수가 상대적 0번이 된다)
클라이언트 -> 서버 (ACK Bit = 1)
- 서버에서 보낸 응답을 확인하므로서 서버가 LIVE 하다는 것을 확신하고 수신/송신 용 BUFFER를 ESTABLISH 한다.
- 응답에 대한 응답으로 받은 패킷의 SEQ number + 1로 ACK를 세팅하고 보낸다.
서버
- 클라이언트로부터 응답을 받은 서버는 클라이언트가 제대로 연결을 했다는 것을 확인하고 수신/송신 용 BUFFER를 ESTABLISH 한다.
세그먼트 전송 예시
클라이언트 -> 서버 (ACK bit = 1, PSH bit = 1)
- 클라이언트가 서버에 데이터를 담은 패킷을 보낸다.
- SEQ가 8001이란 것은 전달할 DATA의 시작 Byte 주소가 8001이란 것이다.
- DATA를 보면 전달하는 데이터의 길이는 1000임을 알 수 있다.
- ACK는 이전에 받은 패킷의 SEQ + 1로 세팅해서 전달한다.
클라이언트 -> 서버 (ACK bit = 1, PSH bit = 1)
- 한번 더 보낸다.
- DATA는 9001 ~ 10000을 보낸다. 시작 Byte는 9001이므로 SEQ도 9001이다.
- PUSH가 활성화 되었으므로 수신측 서버는 버퍼에 있는 데이터를 쭉 읽어들여서 애플리케이션 계층으로 올리게 된다.
서버 -> 클라이언트 (ACK bit = 1)
- piggybacking 이다. (데이터 + ACK 조합)
- cumulative ACK이다. (수신받은 패킷을 누적하여 응답함)
- 전달하는 DATA가 15001 ~ 17000으로 시작하는 Data Byte가 15001이므로 SEQ도 15001이다.
- ACK는 전달받은 데이터의 길이가 1000이고 시작 주소는 9001이였으므로 다음에 받을 byte 번호는 9001 + 1000로 10001이 된다. (다음에 받을 byte 주소)
클라이언트 -> 서버 (ACK bit = 1)
- 그냥 쌩 ACK 세그먼트이다.
- 데이터가 포함되지 않는 경우 SEQ는 보낼 데이터의 시작 Byte주소가 아닌 보냈던 데이터의 마지막 byte 주소가 된다.
- 따라서 이전에 보낸 9001 ~ 10000 데이터의 마지막인 10000이 된다.
- ACK는 상대방으로부터 받을 다음 Byte주소가 된다. 받은 SEQ + 데이터 길이이다.
TCP Connection Termination
4-way handshake 방식
클라이언트 -> 서버 (FIN = 1)
- 종료를 원하므로 FIN Bit를 활성화해서 보낸다.
서버 -> 클라이언트
- 서버는 FIN 요청을 받고 ACK를 보낸다.
- 클라이언트에게 보내야할 패킷이 남아있다면 마저 보낸다.
- 다보내고 난 후 클라이언트에게 FIN을 보내고 서버를 CLOSE 한다. Buffer가 할당해제된다.
클라이언트 -> 서버
- 클라이언트는 FIN 요청을 받고 ACK를 보낸다.
- 서버로부터 받아야할 패킷이 남아있을 수 있으므로 일정시간 기다린다. 이후 받을거 다 받고 CLOSE한다.
반응형
'CS > OSI 7계층 정리' 카테고리의 다른 글
네트워크 정리 : Transport Layer _ Window Control (Flow Control & Congestion Control) (0) | 2021.11.12 |
---|---|
네트워크 정리 : Transport Layer _ TCP Error Control - ARQ (0) | 2021.11.07 |
네트워크 정리 : Transport Layer _ UDP (0) | 2021.10.22 |
네트워크 정리 : Layer 4&5 주소체계와 DNS (0) | 2021.10.15 |
네트워크 정리 : Layer 2&3 주소체계 (MAC, IP) (0) | 2021.09.27 |
Comments
반응형
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday