Может ли запись в сокет UDP когда-либо блокироваться?

И если да, то на каких условиях? Или, говоря по-другому, безопасно ли запускать этот код внутри Twisted:

class StatsdClient(AbstractStatsdClient):
  def __init__(self, host, port):
    super(StatsdClient, self).__init__()
    self.addr = (host, port)
    self.server_hostname = socket.gethostname()
    self.udp_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

  def incr(self, stat, amount=1):
    data = {"%s|c" % stat: amount}
    self._send(data)

  def _send(self, data):
    for stat, value in data.iteritems():
      self.udp_sock.sendto("servers.%s.%s:%s" % (self.server_hostname, stat, value), self.addr)

person Alex Gaynor    schedule 24.01.2013    source источник
comment
Я считаю, что он блокируется по умолчанию, и вы должны использовать self.udp_sock.setblocking(0), чтобы установить его в неблокирующий режим, и в этом случае он вызовет исключение, если не сможет отправить данные немедленно.   -  person imreal    schedule 24.01.2013


Ответы (2)


Да, как ни странно, UDP-сокет может блокироваться.

Условия, при которых это может произойти, в основном таковы: некоторые буферы где-то заполняются, ваша операционная система решает, что пришло время что-то заблокировать. Возможно, это ошибки ядра, но я видел их то тут, то там. Вы определенно можете получить EWOULDBLOCK иногда в неясных, невозможных для воспроизведения условиях.

Почему вы хотите сделать это в Twisted вместо использования встроенной поддержки UDP Twisted?

person Glyph    schedule 24.01.2013
comment
Кроме того, конкретно для Python, если хост должен быть разрешен, Python с радостью сделает это для вас, блокируя, независимо от состояния сокета UDP. - person Jean-Paul Calderone; 24.01.2013
comment
Ах да, и что-то связанное с этим, я думаю, socket.gethostname тоже может блокировать! - person Jean-Paul Calderone; 24.01.2013

Это может привести к сбою, если ваш сетевой интерфейс выйдет из строя, например:

[ENETDOWN] Локальный сетевой интерфейс, используемый для доступа к месту назначения, не работает.

person saghul    schedule 24.01.2013
comment
Это состояние сбоя, а не состояние блокировки. - person zigg; 24.01.2013