当我在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跳之后被丢弃,所以它们不应该到达目的地,这只是为了模拟传出流量。
问题:
这段代码会抛出一个OSError(55,没有可用的缓冲区空间)错误,而在Linux(也是BlockingIOError)上,它抛出一个BlockingIOError,这很好,因为它是一个非阻塞的套接字。
因此,在linux和windows上,套接字在OSX上的行为是正确的--这是一个OSError,这很糟糕。
但真正有趣的是,即使我将这个套接字放入阻塞模式,这段代码仍然会在OSX上抛出一个错误。在linux和windows上,这不会引发任何错误,就像预期的那样,它只是阻塞。
这是基于BSD系统的实现细节吗?还是我错过了一些重要的网络设置?
编辑
我忘了说我是在千兆位网络上测试这种行为。我想这就是问题所在。我连接到了一个100 with的网络,问题就消失了,即使是300 with的wlan,问题也没有发生。
现在,我认为这是一些特定的行为时,连接到高速网络。
最后我终于找到了原因:
http://lists.freebsd.org/pipermail/freebsd-hackers/2004-January/005369.html
在BSD系统上,sendto永不阻塞,文档是错误的。当连接到高速局域网时,混合了一些OSX特有的问题。总体上:只是不要认为sendto阻塞,它没有对BSD。好消息是:如果你知道这一点,你可以考虑到这一点。
发布于 2017-07-13 10:36:04
我还能够隔离这个OSX问题,正如您在这个相关的问题中所看到的:Non-blocking DatagramChannel throws SocketException ("No buffer space available") on OSX but UDP packet is still successfully sent in full
感觉就像个虫子。
https://stackoverflow.com/questions/21973661
复制相似问题