我正在编写一个简单的基于UDP的客户端/服务器应用程序并使用localhost上的客户端/服务器进行测试,我希望发件人知道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秒和设置一个小接收缓冲区之间,我原本预计缓冲区已经填满了。但是,它永远不会。那么如何让接收缓冲区填满以便发送块?
我正在使用Mac OS Lion和Macports版本的Python 2.6。
答案 0 :(得分:4)
UDP通常不会阻止。如果接收器具有完整缓冲区,则数据包将被静默丢弃。这是设计的。如果您想要可靠的传输和阻塞语义,请改用TCP。
评论:TCP阻止的原因是因为发送方对其发送的每个数据包都进行了确认。发件人只允许一定数量的“传输中”没有确认的数据,并在达到此阈值时阻止。由于UDP不发送接收数据包的确认,因此发送方无法知道何时阻止。当然,它可能决定阻止它是否使其以太网端口饱和,但是使用UDP时无法判断您的上行链路是否已饱和,接收器是否挂起,或者gremlins是否吃了您的数据包。不保证!