如何使UDP的send()阻塞?
我正在写一个简单的基于UDP的客户端/服务器应用程序,并且在本地测试客户端和服务器。我希望发送方能够知道什么时候send()会被阻塞。我使用的是Python,所以我想我可以这样做:
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.setblocking(0)
s.connect(('127.0.0.1', 12345))
data = "x"
for i in range(0, 9000): # More than about 9000 gives an error
data += x
while True:
try:
s.send(data)
except socket.error as e:
print "Would have blocked"
# Do something useful here
我想测试我的错误处理代码是否有效,所以我希望send()会想要阻塞。问题是,我不知道该怎么做。我尝试过:
BUFFSIZE = 2000
input = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
input.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, BUFFSIZE)
input.bind(('127.0.0.1', 12345))
while True:
data = input.recv(BUFFSIZE)
time.sleep(100)
在睡眠100秒和设置一个小的接收缓冲区之间,我本以为缓冲区会填满。然而,它从来没有填满。那么我该如何让接收缓冲区填满,以便send被阻塞呢?
我使用的是Mac OS Lion和Macports版本的Python 2.6。
1 个回答
5
UDP通常不会阻塞。如果接收方的缓冲区满了,数据包就会被悄悄丢弃。这是设计使然。如果你想要可靠的传输和阻塞的效果,应该使用TCP。
评论:TCP之所以会阻塞,是因为发送方会对每个发送的数据包进行确认。发送方只允许一定量的数据在“传输中”,这些数据还没有得到确认,当达到这个限制时就会阻塞。由于UDP不发送收到数据包的确认,发送方就无法知道什么时候该阻塞。当然,如果它的以太网端口被占满,它可能会选择阻塞,但在UDP中,没有办法知道你的上行连接是否被占满,接收方是否卡住,或者数据包是否被“怪物”吃掉了。没有任何保证!