我在使用两台主机之间的udp非阻塞读取时遇到了消息丢失的问题。发送者位于linux上,接收者位于winxp上。以下python示例展示了这个问题。
这里有三个脚本用于展示这个问题。
send.py:
import socket, sys
s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
host = sys.argv[1]
s.sendto('A'*10, (host,8888))
s.sendto('B'*9000, (host,8888))
s.sendto('C'*9000, (host,8888))
s.sendto('D'*10, (host,8888))
s.sendto('E'*9000, (host,8888))
s.sendto('F'*9000, (host,8888))
s.sendto('G'*10, (host,8888))
read.py
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind(('',8888))
while True:
data,address = s.recvfrom(10000)
print "recv:", data[0],"times",len(data)
read_nb.py
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind(('',8888))
s.setblocking(0)
data =''
address = ''
while True:
try:
data,address = s.recvfrom(10000)
except socket.error:
pass
else:
print "recv:", data[0],"times",len(data)
示例1(正常工作):
ubuntu> python send.py
winxp > read.py
read.py返回以下结果:
recv: A次数10
recv: B次数9000
recv: C次数9000
recv: D次数10
recv: E次数9000
recv: F次数9000
recv: G次数10
示例2(消息丢失):
在这种情况下,短消息通常无法被read_nb.py捕获,我提供两个示例。
ubuntu> python send.py
winxp > read_nb.py
read_nb.py返回以下结果:
recv: A次数10
recv: B次数9000
recv: C次数9000
recv: D次数10
recv: E次数9000
recv: F次数9000
上面缺少了最后10个字节的消息
以下是中间缺失的10个字节消息
recv: A次数10
recv: B次数9000
recv: C次数9000
recv: E次数9000
recv: F次数9000
recv: G次数10
我已经在Windows上使用wireshark检查过,每次所有消息都被捕获,因此它们达到了主机接口但未被read_nb.py捕获。这是为什么?
我还尝试过在Linux上使用read_nb.py,然后在Windows上使用send.py,然后它可以正常工作。所以我认为这个问题与winsock2有关。
或者我可能错误地使用了非阻塞的UDP?