컴퓨터네트워크

5. 트랜스포트 계층 2-1

waterclean101 2023. 10. 27. 10:33

컴퓨터 네트워크 애플리케이션계층2

 

지난 강의 정리

각 레이어는 자기 자신의 상위 레이어에게 서비스를 제공해주고 하위 레이어로부터 서비스를 제공받는 관계에 있다. 트랜스포트 레이어에는 현재 두 개의 프로토콜이 대표적으로 자리를 잡고 있다. TCP와 UDP. 그런데 TCP든 UDP든 간에 트랜스포트 레이어 프로토콜로서 기본적으로 상위 레이어인 애플리케이션 레이어에게 서비스를 해 주는 기능이 있다. 기본적으로 이 두 가지는 ‘무조건’ 해줘야 한다. 바로 멀티플레이싱에러 체킹.

애플리케이션 프로세스와 애플리케이션 프로세스 간에 의사소통, 프로세스와의 통신인데 수많은 프로세스들이 존재할 거고 반대편 역시 많은 프로세스 존재한다. 전송된 메시지를 받아서 많은 프로세스 중 하나로 올려줘야 하는데, 멀티플렉싱 기능은 기본적으로 트랜스포트 대칭해 해주고 에러 체킹, 트랜스포트 레이어를 사용해서 전달한 메시지는 혹시라도 에러가 있었을 경우 위로 안 올려보낸다. 그래서 UDP가 아무것도 안 해주는 것 같지만 사실은 두 가지 기본적인 기능을 해주는 것. 그래서 에러가 발생한 어떤 메시지는 절대로 리시버 프로세스로 전달되지 않는다.

TCP는 좀 더 다양한 기능을 제공해준다.

 

Principles of Reliable Data Transfer

TCP에서 필요한 reliable한 데이터 트랜스포트를 제공하기 위해서 어떤 메커니즘들이 필요하고 실제로 그 원리는 무엇인가에 대한 이야기

  • reliable: 애플리케이션에서 내려온 메시지가 하나도 유실되지 않고 에러 없이 반대편까지 전달되는 것을 의미
  • 트랜스포트는 아래 계층을 통해 메시지가 라우터를 거쳐서 가는데 실제적인 이 언더라인 네트워크는 사실은 unreliable 하다. 가다가 어떤 라우터에 큐가 꽉 차 있으면 패킷들에서 로스, 패킷 유실이 발생하고 어떤 케이블이 좀 이상하면 거기에 에러가 발생하는 거고 많은 예상하지 못하는 문제가 있다. 트랜스포트 레이어 서비스가 reliable 데이터 통신을 제공하는 것 같지만 사실은 환상일 뿐이다. 이런 unreliable한 현실적인 네트워크 상황에서 발생하는 것은 패킷 에러 or 패킷 로스. 이 두 가지 사항만 잘 처리하면 reliable하게 만들 수 있다.

 

필요한 메커니즘

  • 상대방이 에러 없이 메시지를 받게 하려면 먼저 에러가 나는지 안 났는지 판단해야 할 필요가 있다. 에러 디텍션 → 체크섬
  • 패킷에 체크섬이라는 부가적인 정보를 붙여서 헤더에 담아 보내면된다. 체크섬은 실제 패킷이 담긴 메시지에 에러가 있는지를 판단하기 위한 장치
  • receiver가 패킷을 받았는데 패킷 에러가 있다면? 잘 받았는지 또는 못 받았으니 다시 보내달라고 요청을 하는 등 ‘피드백’이 필요. 긍정적이든(ACKs: Acknowledgements) 부정적이든(NAKs: Negative acknowledgements) 피드백을 줘야 함.

에러가 있는 상황에서 필요한 메커니즘은 바로 에러 디텍션, 피드백, 재전송.

 

Can this completely solve errors?

위의 메커니즘을 가지고 완벽하게 신뢰성 있는 메시지 교환을 할 수 있을까? 만약 ACKs or NAKs ****피드백에 에러가 있다면?

  • sender가 패킷을 보내서 receiver가 잘 받았고 ACKs 피드백을 sender에게 보낸 상황에서 가다가 이 피드백 자체에 에러가 생겼다면 sender는 피드백을 받았을 때 이게 애크인지 내크인지 모르고, 이 피드백 자체가 에런지 아닌지도 알 수가 없다. 따라서 데이터 패킷 뿐만 아니라 이 피드백 패킷에도 체크섬이 필요하다.
  • 체크섬 다음, 피드백을 받았는데 체크섬을 확인해보니 에러인 경우 sender 측에서는 receiver가 ACKs를 보낸건지, NAKs를 보낸건지 판단이 안되니까 다시 보내는 게 그냥 직관적인 해결책이다. 그런데 리시버 입장에서는 다시 받은 패킷이 중복된 패킷인지 아니면 새로운 패킷인지 알 수 없는 것이 문제. 해결 방법은? 그냥 넘버 붙이기. 이 것을 시퀀스 넘버라고 한다.
  • 시퀀스 넘버는 패킷의 부가적인 정보가 담기는 헤더 부분에 들어간다. 그런데 또 문제가 시퀀스 넘버를 그냥 숫자로 한다면 무한대까지 갈 수 있는데 시퀀스 정보 필드의 크기가 매우 커진다. 헤더 부분에는 최소한의 필드들만 사용해야 될 뿐만 아니라 각 필드들의 크기는 가능한 최소의 크기가 되어야 하는데 시퀀스 넘버를 그냥 숫자로 하면 안된다. 이 문제는 사실 한 비트로 해결할 수 있다. 0과 1을 번갈아 가면서, 0 받았으면 그 다음에 1. 1 받았으면 그 다음에 0.
  • ACKs와 NAKs를 바꿔가면서 보내는 건 좀 귀찮고 복잡하다 하면 실제 원리는 똑같은데 NAKs를 없애는 프로토콜도 가능. sender가 보내면 receiver는 무조건 ACKs만을 보내는데 에크 피드백 안에 시퀀스 넘버를 적어 보내줘야 한다. 0과 1중 가장 마지막으로 제대로 받은 번호.

 

channel with loss & packet errors

  • sender가 메시지를 보냈는데 그 메시지가 유실되어 receiver가 받지 못했다면 receiver는 피드백을 보내지 못한다. 즉, sender 입장에서는 메시지 피켓 보내고 나서 아무 피드백도 못 받은 것. 이 때 필요한 것은? Timer
  • 그럼 과연 이 타이머의 시간을 얼마로 제한을 두어야 하는지의 문제가 발생한다. 정확한 숫자로 몇 초. 이렇게 정하기는 어렵고, ACK를 위해 “reasonable”한 시간을 기다린다. 항상 타이머에는 트레이드오프가 있기 때문에 수치로 정하기 어렵다.
  • 타이머의 시간이 굉장히 짧다면? 실제로 유실이 일어났을 경우에 sender에서 리커버리, 리액션이 빠르다. 단점은 혹시라도 패킷 멀리 돌아가서 아직 도달을 안했을 뿐인데 sender 측에서 다시 재전송을 해버려서 네트워크에 중복된 패킷들이 나가고 이는 네트워크 오버헤드를 준다.
  • 반대로 이 타이어가 굉장히 길다면? 장점은 네트워크 오버헤드가 적다. 단점은 로스가 발생했을 때 반응이 느리다.