如何使UDP的send()阻塞?

1 投票
1 回答
1910 浏览
提问于 2025-04-17 06:44

我正在写一个简单的基于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中,没有办法知道你的上行连接是否被占满,接收方是否卡住,或者数据包是否被“怪物”吃掉了。没有任何保证!

撰写回答