MQTT Final Review

wldbs._.·2024년 9월 23일

MQTT

목록 보기
7/7
post-thumbnail

1. CONNECT, PUBLISH, SUBSCRIBE 패킷 상세 분석

오픈소스 MQTT Server(Mosquitto)와 WireShark를 활용하여 MQTT Control Packet을 자세히 바라보자.
상세 패킷을 분석하며 그림판에 직접 정리해보자.


1) CONNECT

1) 고정 헤더

: control packet type(7~4번 bit) + flags(3~0번 bit) + remaining length(7~0번 bit)

  • connect 타입의 value는 1 -> 0001, client -> server, 서버 연결 요청

  • flags = DUP(3번 bit) + QoS level(2~1번 bit) + RETAIN(0번 bit) -> connect는 flags가 0000으로 reserved

[1] DUP (Duplicate flag) : 0일 경우, 첫번째 전달 시도임을 의미하며, 1일 경우에는 이전에 전달된 Packet이 재전송 Packet이라는 것을 의미한다. (QoS > 0)
[2] QoS : QoS 레벨
[3] Retain : 1일 경우, 서버는 해당 Topic의 최종 내용을 저장하고 있다가 향후 구독하는 Client에게 이를 전달한다.

  • Msg Len = remaining length : 고정 헤더를 제외한 메시지의 나머지 부분의 길이가 12byte (가변헤더, 페이로드 포함)

2) 가변 헤더

: protocol name, protocol version, connect flags, keep alive

  • protocol name length : MQTT 프로토콜 이름의 길이가 4byte

  • protocol name : 프로토콜 이름이 MQTT

  • version : MQTT 프로토콜 버전 3.1.1 = 프로토콜 버전 번호 4

  • connect flags = username(0) + password(1) + will retain(2) + QoS level(3~4) + Will(5) + Clean Session(6) + Reserved(7번 bit)

    • 사용자 이름 포함 여부 = 0 (포함 X)
    • 비밀번호 포함 여부 = 0
    • Will 메세지의 Retain 플래그 = 0
      • Will Retain 플래그가 설정되어 있으면, 브로커는 Will Message를 해당 주제(Topic)에 유지하고,
      • 이후에 해당 주제를 구독하는 새로운 구독자에게도 Will Message를 전달
    • Will 메시지의 QoS level = 00
    • Will 메시지 포함 여부 = 0
      • Will 메시지? -> Client는 자신이 접속 종료되었을 때 '특정 Topic에 대한 메시지'를 발송하라고 Server에 등록
      • Will Message는 하나의 클라이언트당 단 하나의 메시지와 단 하나의 주제(토픽)만 설정할 수 있다!
    • Clean Session 플래그 = 1 (true, 클라이언트가 연결이 종료될 때 세션을 초기화)
    • 예약됨 reserved = 0
  • keep alive : 클라이언트의 최대 무활동 시간(초) = 60(default) -> 60초 동안 클라이언트가 데이터 전송을 하지 않으면 connection 연장을 위해 60초가 되는 시점에 PINGREQ 메시지를 보내어 연결이 유지되고 있음을 확인

    • PINGREQPINGRES는 연결 확인을 위한 목적으로 사용되는데, 고정 헤더로만 구성되어 있다!
    • MESSAGE TYPE의 VALUE는 각각 12와 13
    • FLAGS는 0으로 예약됨
    • REMAINING LENGTH = 0
      • -> C0 00D0 00으로 주고 받는다

3) 페이로드

: client id, will topic, will message, user name, password

  • client id : 클라이언트를 구분하는 고유 식별자, 따로 설정 X -> 길이가 0

  • client id가 지정되어 있다면, client id length 다음에 client id가 utf-8 encoding되어 나타난다.


2) PUBLISH (QoS 0)

1) 고정 헤더

: control packet type(7~4번 bit) + flags(3~0번 bit) + remaining length(7~0번 bit)

  • publish 타입의 value는 3 -> 0011, client <-> server, 발행
  • flags = DUP(3번 bit) + QoS level(2~1번 bit) + RETAIN(0번 bit) -> publish는 flags 고정 X
    • DUP = 0 -> 첫번째로 패킷 전달 시도
    • QoS = 0 -> QoS level이 0
    • Retain = 0 -> 향후 구독하는 클라이언트에게 해당 토픽의 최종 내용 전달 X
  • Msg Len = remaining length : 고정 헤더를 제외한 메시지의 나머지 부분의 길이가 9byte (가변헤더, 페이로드 포함)

2) 가변 헤더

: topic, topic length, packet id(if QoS>0) (required)

  • topic length : 토픽 이름의 길이가 4byte
  • topic : 발행된 메시지가 할당된 토픽의 이름이 cook

3) 페이로드

: application message (optional)

  • Message : 메시지 내용이 16진수로 표시됨, ASCII 값으로 변환하면 메시지의 내용을 알 수 있다!

3) SUBSCRIBE (QoS 0)

1) 고정 헤더

: control packet type(7~4번 bit) + flags(3~0번 bit) + remaining length(7~0번 bit)

  • subscribe 타입의 value는 8 -> 1000, client <-> server, 서버 구독 요청
  • flags = DUP(3번 bit) + QoS level(2~1번 bit) + RETAIN(0번 bit) -> subscribe0010으로 reserved
    • DUP = 0
    • QoS = 1 -> QoS level이 1, QoS 1은 "최소 한 번 이상 전달"로, 클라이언트는 브로커로부터 전달 성공 여부를 확인받게 된다!
    • Retain = 0
  • Msg Len = remaining length : 고정 헤더를 제외한 메시지의 나머지 부분의 길이가 9byte (가변 헤더, 페이로드 포함)

2) 가변 헤더

: packet id (required)

  • 클라이언트가 특정 메시지 타입(SUBSCRIBE, UNSUBSCRIBE, PUBLISH(QoS 1, 2), PUBREL, PUBREC, PUBCOMP)에서 사용되는 메시지의 순서를 추적하고 관리하기 위해 클라이언트 측에서 자동으로 생성하는 고유한 숫자
  • 일반적으로 Packet Identifier는 클라이언트가 처음 메시지를 전송할 때 자동으로 설정되며, 매 메시지마다 증가
  • Message identifier = packet id : subscribe 메시지의 패킷 식별자, 클라이언트가 메시지를 전송할 때 부여한 고유한 식별자, 브로커로부터 응답을 받을 때 이 식별자를 사용하여 구독 요청과 응답을 매칭 (여기서는 1로 설정됨)

3) 페이로드

: topic length, topic, requested QoS

  • Topic Length : 토픽 이름의 길이가 4byte, 2바이트로 인코딩된다.
  • Topic : 구독하고자 하는 토픽 이름 cook, 각 문자가 UTF-8로 인코딩되어 4바이트를 차지
    • ASCII 문자(영문자, 숫자, 기본 특수 문자)는 UTF-8에서도 같은 바이트로 인코딩되기 때문에, ASCII 범위의 문자는 UTF-8과 완전히 호환
  • Requested QoS : 요청된 QoS 수준, 여기서는 "최소 한 번 이상 전달"을 의미하는 QoS 1이 요청되었다.

2. 그림판 정리





3. ChatGPT 답변

1) Clean Session

2) Broker-QoS

: Mosquitto 브로커는 기본적으로 클라이언트 간의 QoS 수준을 조정하고 처리할 수 있지만, 자체적으로 QoS 레벨을 설정하지는 않는다.

  • 그러나 브로커 설정을 통해 최대 QoS 레벨을 제한하는 등의 제어 가능
  • mosquitto.conf 파일을 통해 클라이언트가 사용할 수 있는 최대 QoS 수준을 설정할 수 있다!
    • mosquitto.conf 파일의 max_qos 설정을 통해 클라이언트가 사용할 수 있는 최대 QoS를 제한하여 자원 관리 가능
    • -> 클라이언트가 더 높은 QoS를 요청해도 브로커는 설정된 최대 QoS 이하로 낮추어 처리

3) QoS-Store Message

  • 발행자는 MQTT 프로토콜에서 메시지를 발행한 후, 특정 QoS(1 또는 2) 수준에서는 메시지를 메모리에 저장해두고, 브로커로부터 발송 확인(Acknowledgement)을 받으면 그 메시지를 삭제
  1. QoS 0: 발행자는 메시지를 브로커로 한 번만 전송, 브로커로부터 메시지의 수신 확인을 기다리지 않음, 메시지를 전송한 후 즉시 메시지를 삭제
  2. QoS 1: 발행자는 브로커로 메시지를 발행한 후, 브로커로부터 메시지의 수신 확인(PUBACK)을 받기 전까지 메시지를 메모리에 저장 gkekrk PUBACK 패킷을 받으면 메시지를 삭제
  3. QoS 2: 발행자는 브로커로 메시지를 발행한 후, 브로커와 4단계의 핸드셰이크 절차(PUBREC, PUBREL, PUBCOMP)를 통해 메시지가 정확히 한 번만 전달되도록 보장, 발행자는 브로커로부터 PUBCOMP 패킷을 수신한 후에 메시지를 삭제
  1. QoS 0: 브로커는 발행자로부터 메시지를 수신하면 현재 연결된 구독자에게 즉시 메시지를 전달, 메시지를 전송한 후 브로커는 메시지를 저장하지 않는다, 메시지가 구독자에게 전달된 후 즉시 메시지를 삭제
  1. QoS 1: 브로커는 발행자로부터 메시지를 수신한 후 구독자에게 메시지를 전송, 구독자에게 메시지를 전송하고 구독자로부터 ACK 응답을 수신한 후 메시지를 삭제
  1. QoS 2: 메시지가 구독자에게 완벽하게 도달할 때까지 모든 핸드셰이크 절차가 완료되기 전까지 메시지를 저장, 브로커는 구독자로부터 COMP 패킷을 수신한 후에야 메시지를 삭제
  1. Clean Session: 구독자가 Clean Session = False로 설정되어 있다면, 브로커는 구독자가 오프라인 상태일 때도 해당 구독자의 QoS 1 또는 QoS 2 메시지를 저장
  • 구독자가 오프라인 상태? 구독자가 브로커와의 네트워크 연결이 끊어진 상태 -> 구독자는 브로커와의 메시지 전송이나 수신을 할 수 없으며, 구독자가 다시 연결될 때까지 모든 메시지 교환이 중단된다.
  1. Retain: 발행자가 메시지를 Retain = True로 발행한 경우, 브로커는 해당 토픽에 마지막으로 발행된 메시지를 저장, 브로커에 저장된 Retain 메시지는 발행자가 새로운 Retain 메시지를 발행하거나 빈 메시지를 발행하여 Retain 메시지를 지우기 전까지 유지됨

출처

profile
공부 기록용 & 프로젝트 회고용 24.08.05~ #AI/LLM #RAG # Data Science

0개의 댓글