code: def receive_datagram(self):
          
          logger.debug("Start receiver Thread")
          while not self.stopped.isSet():
              self._socket.settimeout(0.1)
              try:
                  datagram, addr = self._socket.recvfrom(1152)
              except socket.timeout:  # pragma: no cover
                  continue
              except Exception as e:  # pragma: no cover
                  if self._cb_ignore_read_exception is not None and isinstance(self._cb_ignore_read_exception, collections.Callable):
                      if self._cb_ignore_read_exception(e, self):
                          continue
                  return
              else:  # pragma: no cover
                  if len(datagram) == 0:
                      logger.debug("Exiting receiver Thread due to orderly shutdown on server end")
                      return
  
              serializer = Serializer()
  
              try:
                  host, port = addr
              except ValueError:
                  host, port, tmp1, tmp2 = addr
  
              source = (host, port)
  
              message = serializer.deserialize(datagram, source)
  
              if isinstance(message, Response):
                  logger.debug("receive_datagram - " + str(message))
                  transaction, send_ack = self._messageLayer.receive_response(message)
                  if transaction is None:  # pragma: no cover
                      continue
                  self._wait_for_retransmit_thread(transaction)
                  if send_ack:
                      self._send_ack(transaction)
                  self._blockLayer.receive_response(transaction)
                  if transaction.block_transfer:
                      self._send_block_request(transaction)
                      continue
                  elif transaction is None:  # pragma: no cover
                      self._send_rst(transaction)
                      return
                  self._observeLayer.receive_response(transaction)
                  if transaction.notification:  # pragma: no cover
                      ack = Message()
                      ack.type = defines.Types['ACK']
                      ack = self._messageLayer.send_empty(transaction, transaction.response, ack)
                      self.send_datagram(ack)
                      self._callback(transaction.response)
                  else:
                      self._callback(transaction.response)
              elif isinstance(message, Message):
                  self._messageLayer.receive_empty(message)
  
          logger.debug("Exiting receiver Thread due to request")
docs: Receive datagram from the UDP socket and invoke the callback function.