TCP/IP protocol
- 웹 서버를 굳이 80번 포트에서 돌릴 필요는 없다. 하지만 80번을 안 쓸 경우, 꼭 클라이언트가 알아야한다.
- 나머지도 마찬가지. 그냥 약속해놓은거는 정해진 대로 쓰자.
- 보통 다른 어플리케이션은 1023 이후의 포트번호를 할당한다. 포트번호는 보통 16비트이다. 나중에 TCP헤더에서 나온다. 그래서 0 부터 65535의 숫자를 쓴다.
Stream Delivery
- 그냥 정해진 사이즈로 쭉~가는게 스트림 딜리버리이다.
- UDP는 Boundary delivery라는 개념을 쓴다.
Sending & Receiving Buffer
- Sent : 보낸 것의 카피를 의미함. 택배를 보냈을 때 손실이 있을 수 있으니까 재전송이 필요한 것처럼
- Not Sent : 아직 안나간 데이터들을 의미함.
- Empty : 아직 어플리케이션에서 안 쓴 부분.
- Sending 버퍼의 Sent는 추후에 핸드쉐이킹 과정에서 받았다는 것이 확인 완료되면 비워진다.
TCP Topics
- Numbering System
- Flow Control
- Error Control
- Congestion Control
Numbering System
- TCP는 소실된 패킷을 복구할 수 있다. 이걸 Numbering System으로 구현을 함.
- 숫자는 32비트짜리 숫자중에서 랜덤하게 선정한다.
- 패킷들 중 부여하는 첫번째 번호는 Sequence Number라고 한다.
- Selective ACK과 Cumulative ACK이 존재함.
- 우리가 현재 쓰는 것은 Cumulative방식임. 하지만 이게 좀 비효율적이여서 나중엔 SACK옵션을 채택해서 Selective ACK을 사용할 수 있게끔 함.
- 이 헤더 외우는거는 시험에도 나왔음.. 위치 외우는거..
- HLEN은 20에서 60까진데, 고정된 값이 절대 아님. HLEN을 통해 알 수 있는것임.
- 비트수를 아끼기 위해, 4로 나눠서 HLEN에다가저장하는 것임.
- TCP 세그먼트에는 Pseudoheader라는게 추가가 된다.
- 슈도 헤더는 체크 섬만 구하는 용도이고, 전송은 하지 않는다.
- 패킷을 받는 입장에서는 Frame에서의 CRC검사, IP에서의 checkSum검사, TCP에서 checkSum검사를 수행한다.
- 근데 IP헤더를 갖고 한번 더 검사한다.
- 체크섬을 계산하는 방법은 16비트씩 잘라서 각각을 Sum한다.
- 그 다음, 보수를 취한다.
- 받은 쪽에서도 이를 이용해서 에러를 검사하면 된다!
- Q. 체크섬은 에러 판별에 완벽한 수단인가?
- A. NO.정교한 알고리즘을 넣기에는 헤더가 너무 커지기 때문이다.
- payload라는 것은 데이터에 해당하는 영역임.
- three way hand shake에 해당하는 과정.
- SYN 패킷은 연결 요청 패킷. 랜덤하게 번호를 생성한다.
- 상대방은 SYN+ACK을 보낼 때 15000이라는 번호를 랜덤하게 생성한다.
- 이거랑 똑같은 그림임! 함수들을 잘 보자.
- server에서는 socket, bind, listen함수를 통해서 세팅하고
- accept를 통해 받을 준비를 한다
- 클라이언트는 socket함수를 호출한뒤, connect를 통해 연결 시도를 한다. 언제까지? SYN+ACK이 서버로부터 올 때까지!
- 이건 종료시에 3-way handshake이다!
- 근데 이것보다는 4-way handshake를 쓴다. 종료때문에!
- FIN은 close함수를 통해 보내게 된다. 또는 main함수의 exit이나, Ctrl + C같은 것들이 FIN을 보낸다. 하드웨어적인 종료에 의한것은 보내지 않음! 나중에 이런 경우도 처리하는게 있음.(Keepalive timer)
- 아까 말했던, 4-way handshake과정. 서버에선 ACK을 보내고, 아직 서버에서 보내지 못한 데이터가 남아있을 수 있는 가능성을 고려, FIN을 보내기까지 시간을 남겨둠.
- 이 상태를 Half-close상태라고 함.
- time-wait상태가 없으면 무슨일이 벌어질까?
- 서버는 IP주소와 port번호로 client를 구분을 한다!
- Time-wait상태가 없으면, 서버가 기존에 쓰던 port번호를 줄 확률이 굉장히 높다. 그래서 Time-wait을 두는것.
Flow Control
- sliding window라는 기법을 통해 송신자가 보내는 속도를 조절하는 기술임
- TCP는 하나 보내고 응답 하나 받는게 아니라, 하나를 보낼 때 좀 많이 보낸다.
- 얼만큼? rwnd만큼.
- 근데 이제 Silly Window Syndrome이라는게 있음.
- 송신측에서 발생하는 신드롬 : 데이터 1 바이트 보내려고 40 바이트를 써야하는게 너무 비효율적임. 즉, 보내는 데이터에 비해서 헤더의 데이터가 큰 경우 너무 비효율적.
- 그래서 Nagle알고리즘이 등장함.
- 첫번째꺼는 그냥 보내고, 그리고 ACK이 오기 전까지 나머지 데이터들은 대기시켜놓음. 얼마나? Maximal waiting time동안.
- 만약 ACK이 오기 전에 보낼 윈도우 사이즈에 다 찼을 경우, 바로 보냄!
- 수신측에서 발생하는 신드롬 : 송신측에서 발생하는 신드롬이 수신측 때문에 발생할 수도 있다!
- 빈공간이 1이라고 할 때, 실제로는 rwnd를 0으로 해서 보낸다.
- Clark 알고리즘 : 빈공간이 버퍼의 반이 비어있기 전까지나, maximum segment size만큼 비어있을 때까지 rwnd=0으로 해서 보낸다.
- 확인 응답의 지연 : ACK을 그냥 보내지 않는것. 근데 이건 문제가 생길 수 있음.(타임아웃)
- SYN Flooding이란? 여러 명의 클라이언트가 SYN을 보내면 서버에서 SYN+ACK을 보내지만 다시 클라이언트에서 ACK을 보내진 않는다.
- 이러면 연결 요청 대기큐에 엄청 쌓이게 되고, 더 이상 서비스를 못하게 됨!
- TCP에는 여러 룰이 존재함.
- Rule 1 : Sending buffer에 보낼 데이터가 있으면 데이터랑 ACK이랑 같이 보내자.
- Rule 2 : 데이터를 받아서 ACK을 보내려고 할 때, 데이터가 보낼게 없으면 좀 기다려보자. 언제까지? 없으면 그냥 보내자.(50ms)
- Rule 3 : 데이터 2개 당 ACK을 보내준다.
Error Control
- 여기서부터 문제가 발생하는 상황들을 보여준다.
- Rule4 : 중간에 패킷 loss가 생기면, 받아야하는 패킷의 번호를 보내준다.
- Rule5 : 잃어 버렸던 것을 받으면 바로 확인했다고 보냄!
- Rule6 : 받은 데이터를 받았는데 또 받으면? 받아야하는 순서의 ACK을 보내준다.
- Fast retransmission : 세개의 중복된 ACK(순서로는 네번째)을 받으면? 그제서야 부족한 부분의 데이터를 보내준다.
- 위 사진은 ACK을 못받아도 문제가 안되는 상황을 보여준다.
- 그럼, ACK을 못받으면 문제가 생기는 경우는 무엇일까?
- Clark솔루션을 생각해볼 수 있겠다. 수신측에서 발생하는 silly window syndrom을 막기 위한 알고리즘이었지?
- rwnd = 0을 보내다가 이제 보내도 된다는 신호로 'rwnd = k'를 보냈는데, 이 패킷이 loss가 됐다면?
- 원래 sender는 왜 안오지? 하고 계속 기다릴것이여!
- reciever측에서는 아니 왜 안오지? 하고 또 기다릴것이여
- 이런걸 해결하기 위해 timer라는 개념이 도입이 된것이다.
- 이거를 persistent timer(영속 타이머)라고 하고, 테스트 용도로 보내는 패킷을 probe packet이라고 한다.
Congestion Control
- 혼잡이 생기는 이유?
- 라우터에 메모리 공간은 굉장히 한정적이다.
- 패킷 loss는 99퍼센트 이 혼잡때문에 발생한다!
- TCP에는 Best Effort라는 의미가 있는데, 이 의미에 내포된 말은 보장을 안한다! 라는 의미도 있는것이다.
- TCP에서 그럼 혼잡제어를 어떻게 하는지 중요한 그림!
- TO인 경우에는, threshold를 1/2로 줄이고, 현재 cwnd를 1로 낮춘다!
- 3 dup ACK인 경우, 그냥 현재 cwnd를 1/2로 하는것!
- 요 그림을 예시로 보면 될듯하다
- TCP는 fair하다는것을 보여주는 그림
- 만약 여기서 연결이 더 생긴다면 각 연결을 동등하게 분배한다.