2013-01-24 149 views
14

如果是这样,在什么条件下?或者,交替地措辞,是安全的扭曲中运行这些代码:可以写入UDP套接字吗?

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) 
+0

我相信它默认是阻塞的,你必须使用'self.udp_sock.setblocking(0)'将它设置为非阻塞,在这种情况下,如果它不能立即发送数据,它将引发异常。 – imreal

回答

9

是的,奇怪的是,UDP套接字可以阻止。

发生这种情况的条件基本上是某些缓冲区满了,操作系统决定是时候阻止某些东西了。这些可以说是内核错误,但我已经看到他们在这里和那里。有时您可能会在模糊,无法再现的情况下获得EWOULDBLOCK

为什么你要在Twisted中做到这一点,而不是使用Twisted的built-in UDP support

+3

另外,特别是Python,如果需要解析“主机”,那么无论UDP套接字的状态如何,Python都会很高兴地为你做出这种解决方案。 –

+2

哦,是的,有点相关,我猜,'socket.gethostname'也可以阻止! –

-1

它可能会失败,如果你的网络接口出现故障,例如:

[ENETDOWN]使用的本地网络接口到达目的地已关闭。

+3

这是一种失败情况,而不是阻塞情况。 – zigg

+0

Doh,没错,对不起,我误读了。 – saghul