OS X UDP发送错误:55没有可用的缓冲区空间

当我在OSX10.9.1上的python3.3中实现RUDP时,我注意到下面的代码实际上并没有做它在linux上的工作:(对于C,Java和C#/ Mono来说,哪种语言,同样的行为并不重要)

from socket import * udp = socket(AF_INET, SOCK_DGRAM) udp.setsockopt(SOL_SOCKET, SO_REUSEADDR, True) udp.bind(('0.0.0.0', 1337)) udp.setblocking(False) udp.setsockopt(SOL_IP, IP_TTL, 4) udp.connect(('8.8.8.8', 12345)) buf = b'x' * 400 for _ in range(1024 * 1024 * 10): udp.send(buf) 

这个代码只是写了很多udp包到8.8.8.8,这些包在4跳之后被丢弃,所以他们不应该到达目的地,只是模拟出站stream量。

问题:

这段代码会抛出一个OSError(55,'No buffer space available')错误,而在Linux(Windows)上,它会抛出一个BlockingIOError,这很好,因为它是一个非阻塞套接字

所以,在Linux和Windows上,套接字在OSX上的行为是正确的,这是一个OSError,这是不好的。

但真正有趣的是,即使我把这个套接字置于阻塞模式下,这个代码仍然会在OSX上抛出一个错误。 而在Linux和Windows上,这不会引发任何错误,正如所料,它只是阻止。

这是基于BSD系统的实现细节吗? 或者我错过了一些重要的networking设置?

[编辑]

我忘了提到我正在千兆局域网中testing这种行为。 我认为这是问题。 我连接到一个100mbit的networking,问题就没有了,即使使用300mbit的wlan,问题也没有发生。

现在我想这是连接到高速networking时的一些OSX特定行为。

[编辑 – 最后]我终于find原因:

http://lists.freebsd.org/pipermail/freebsd-hackers/2004-January/005369.html

在BSD系统发送从不阻止,文档是错误的。 当连接到高速LAN时混入一些OSX特定的问题。 总的来说:只是不要认为sendto块,它不在BSD上。 好东西:如果你知道的话,你可以考虑到这一点。

Solutions Collecting From Web of "OS X UDP发送错误:55没有可用的缓冲区空间"

我不认为你的意思是绑定的插座。 这应该只在你打算听的服务器端完成。 如果你放弃呼叫绑定会发生什么? 例如:

 from socket import * import time udp = socket(AF_INET, SOCK_DGRAM) buf = b'x' * 400 for _ in range(1024 * 1024 * 10): while True try: udp.sendto(buf, ('8.8.8.8', 12345)) break except OSError, exc: if exc.errno == 55: time.sleep(0.1) else: raise 

我也能够隔离这个OSX的问题,你可以在这个相关的SO问题中看到: 非阻塞DatagramChannel在OSX上抛出SocketException(“没有可用的缓冲区空间”),但UDP数据包仍然成功发送

感觉就像一个错误。