🛠 TCP를 이용한 통신과정
💡 연결 수립 과정
- TCP를 이용한 데이터 통신을 할 때 프로세스와 프로세스를 연결하기 위해 가장 먼저 수행되는 과정
- 클라이언트가 서버에게 요청 패킷을 보내고
- 서버가 클라이언트의 요청을 받아들이는 패킷을 보내고
- 클라이언트는 이를 최종적으로 수락하는 패킷을 보낸다.
- 위의 3개의 과정을 3Way Handshake라고 부름
- 클라이언트가 패킷을 만들어서 (TCP 인캡슐레이션 + IPv4 인캡슐레이션 + Ethernet 인캡슐레이션) 요청을 보낸다.
- 단순히 연결을 수립하는 과정이기 때문에 TCP 뒤쪽에 페이로드는 없음
- 출발지 포트번호 아무거나 / 목적지 포트번호는 웹이니까 80 --> 16진수로
- 시퀀스번호 / acknowledgemnt number
- 헤더길이 20바이트인데 4로나눠서 5 / reserved 사용X
- Flags인데 02는 싱크 플래그 세팅 / window는 TCP버퍼 공간알려줌
- 체크썸 / urgent pointer
- IPv4, Etherner도 세팅해서 보냄
- flags: 싱크, 시퀀스번호: 100, acknowledgemnt number: 0
- 로 세팅되어서 보내짐
- 요청받은 서버가 ethernet 디캡슐레이션, IPv4 디캡슐레이션, TCP 디캡슐레이션 하여 내용확인 후 응답
- 출발지 포트번호 80 / 목적지 포트번호는 아까 요청받은 포트번호
- 시퀀스번호 / acknowledgemnt number
- 헤더길이 20바이트인데 4로나눠서 5 / reserved 사용X
- Flags인데 12 세팅 / window는 TCP버퍼 공간알려줌
- 체크썸 / urgent pointer
- IPv4, Etherner도 세팅해서 인캡슐레이션 해서 보냄
- flags: 싱크+ACK, 시퀀스번호: 2000, acknowledgemnt number: 101
- 로 세팅되어서 보내짐
- 클라이언트가 ethernet 디캡슐레이션, IPv4 디캡슐레이션, TCP 디캡슐레이션 하여 내용확인 함
- flags에 SYN, ACK를 본다
- ACK는 연결해도 되냐고 물어본것에 대해 해도된다는 대답
- SYN는 서버가 나에게 연결해도되냐고 물어본 것이니까 응답해준다.
- 플래그엔 연결해도 된다고 대답만 하면 됨
- TCP 인캡슐레이션 + IPv4 인캡슐레이션 + Ethernet 인캡슐레이션 후 보냄
네트워크 보안까지 가면 시퀀스번호, acknowledgemnt number 까지 자세하게 알아야 함
- 맨처음 클라이언트가 시퀀스번호, 애크번호를 랜덤값을 보냄
- 애크번호는 받은 시퀀스번호에 +1
- 시퀀스번호는 받은 애크번호와 똑같음
- 동기화 값을 계속 주고받다가 클라이언트가 아닌 다른 누군가가 값을 계산해서 서버에게 보내면 큰일..
💡 데이터 송수신 과정
- TCP를 이용한 데이터 통신을 할 때 단순히 TCP 패킷만을 캡슐화 해서 통신하는 것이 아닌 페이로드를 포함한 패킷을 주고 받을 때의 일정한 규칙
- 보낸 쪽에서 또 보낼 때는 SEQ번호와 ACK번호가 그대로다.
- 받는 쪽에서 SEQ번호는 받은 ACK번호가 된다.
- 받는 쪽에서 ACK번호는 받은 SEQ번호 + 데이터크기
- 연결 수립 할때는 반은 SEQ번호에 +1을 했지만, 뒤에 페이로드가 있는 경우는
SEQ번호 + 데이터크기 임
- 클라이언트가 데이터 보낼때는 연결수립 했을 때의 SEQ번호와 ACK번호 이어서 함
- TCP 인캡슐레이션 하고 IPv4 인캡슐레이션하고 Ethernet 인캡슐레이션
- Flags에 Push랑 ACK 함께 세팅 하고 보냄
- 서버는 디캡슐레이션 하고 데이터 확인하고 답장을 해줌
- 데이터에 TCP, IPv4, Ethernet 인캡슐레이션 하고 보낸다.
- 이때 시퀀스번호는 받은 ACK번호와 동일하게 2001이고
- ACK번호는 받은 시퀀스번호 101+ 데이터크기 100 = 201임
- 이것을 다 디캡슐레이션 해서 데이터 확인한 ( 자기가 원하는 데이터를 받음 ) 클라이언트는 잘 받았다고 답장 해줘야지
- SEQ번호는 201, ACK번호는 2501 세팅해서 인캡슐레이션 해서 보냄
- 데이터까지 주고 받은것, 이제 연결 끊음 됨
🛠 TCP 상태전이도
💡 TCP 연결 상태의 변화
- 데이터 주고받을 떄 SEQ, ACK번호가 바뀌는데,
- 패킷 주고받으면서 한가지 더 변하는 것이 TCP의 연결상태 이다.
- 실선은 클라이언트의 상태변화
- 점선은 서버의 상태변화
- 밑의 네모 안에 들어있는 것들이 상태인데, 빨갛게 체크한 것이 중요
1. LISTEN 상태 ⭐⭐
- 4계층은 포트번호를 사용하는데 이 포트번호를 열어놓고 있는 상태
- 서버쪽에서 포트번호를 사용하고 있는 상태
- 클라이언트의 요청을 항상 듣고있는 상태
2. ESTABLISHED 상태 ⭐⭐
- 연결이 수립이 된 상태
- 실행시킨 해당 서버에 포트번호가 LISTEN상태인지 확인해 봐야함
- 연결상태확인 명령어 : netatat -ano
- 클라이언트와 연결을 하게 되면 ( 3Way Handshake 과정이 끝나면 ) ESTABLISHED 상태가 되는 것 --> 통신이 가능
3. 나머지
- 클라이언트도 본인만의 포트번호를 쓴다
- 원래는 포트가 닫혀있는 상태 ( CLOSED )인데 클라리언트는 포트를 사용할 때 active open 이라고 한다 ( 능동적 )
- <--> 클라이언트 입장에서 서버는 수동적
- active open하면서 서버에게 플래그로 SYN 세팅해서 준다
- 그러면 SYN_SENT 상태가 됨
- 싱크를 받은 서버는 SYN_RECEIVED 상태가 되고 SYN, ACK 패킷을 보냄
이것을 아까 그림으로 보면
- 클라이언트가 패킷 만들어서 보내면 클라이언트는 active open하게 된 것
- 동시에 SYN_SENT 상태가 됨
- 서버는 항상 리스닝 상태이고, 패킷을 받으면 SYN_RECEIVED 상태가 됨
- 패킷을 디캡슐레이션 해서 확인하고 다시 패킷을 만들어서 답장을 하는데
- 그러면 클라이언트는 패킷을 확인하고 패킷에 ACK 세팅해서 보냄
- 클라이언트는 ESTABLISHED 상태가 됨
- 패킷을 받은 서버에서도 ESTABLISHED 상태가 됨
- 서버가 ESTABLISHED 상태가 되어야 서로 데이터 주고받을수 있는 상태가 된 것
👻 실습
1. 인터넷에서 네트워크통신 아무거나 하고 와이어샤크에서 tcp를 확인해보자
- TCP는 워낙많아서 보기 힘들다 그래서 쉽게 보기 위해서
- 하나의 동기화했던 내역 하나만 뽑아서 보자
- TCP 아무거나 우클릭 후 FOLLOW에서 TCP Stream 클릭
- 맨위로 가서 3개를 보면 그것이 3Way Handshake
- Statistics 메뉴에 Flow Graph 클릭해보자
- 그 아래에 Limit to display filter를 누르면 아까 필터 걸어놓은 하나의 내용만 보여준다.
- Seq번호와 ACK번호는 사실 랜덤한 번호가 지정이 되는데 와이어샤크가 보기 편하게 0으로 계산해서 보여주는 것
*preferences에서 protocols에서 TCP에서 Relative sequence numbers를 체크해제 시켜주면 실제 값을 보여준다.
- 이 과정이 지나야 클라이언트와 서버가 ESTABLISHED 상태가 되는 것
- 이 3개가 지나고 데이터를 뭔가 주고받은 것임
- 일반적으로 3Way Handshake가 끝나면 맨처음 요청한 클라이언트에서 다시 클라이언트가 먼저 요청을 시작한다.
- 마지막에 끝났던 SEQ, ACK번호를 그대로 이어서 쓴다.
- 서버의 ACK는 클라이언트가 보낸 데이터 + SEQ가 됨