套接字在UDP中丢失部分消息

时间:2017-10-21 00:39:19

标签: python python-2.7 sockets server

我正在尝试使用Python 2.7通过UDP套接字发送图像帧,我尝试发送的当前帧是921600字节(640 x 480)。并且UDP消息的缓冲区限制为65507个字节,所以我需要拆分消息,这就是我的工作方式。

来自client.py

image_string = frame.tostring()              # frame is an multi-d numpy array
message_size = len(image_string)
sock.sendto(str(message_size), (HOST, PORT)) # First send the size

for i in xrange(0, message_size, 65507):     # Split it and send
    sock.sendto(image_string[i:i + 65507], (HOST, PORT))

sock.sendto("\n", (HOST, PORT))              # Mark the end to avoid hanging.

以下是我在server.py中接收它的方法,我插入了一些打印用于调试。

image_string = ""

data, addr = sock.recvfrom(1024) # recieve image size
message_size = int(data)
print "Incoming image with size: " + data

for i in xrange(0, message_size, 65507):
    data, addr = sock.recvfrom(65507)
    image_string += data.strip()
    print "received part, image is now:", len(image_string)

print "End of image"

所以我正在以同样的方式阅读信息,它在理论上检查,但实际上没有。可能是因为客户端完成发送后丢失了一些数据包 - 服务器仍然试图读取(被阻止)。

我知道UDP不可靠且难以使用,但我读到UDP在许多视频流应用程序中使用,所以我相信应该存在解决这个问题的方法,但我找不到它。

感谢所有帮助,谢谢。

Edit1:我怀疑数据包丢失的原因是问题,因为每次运行测试时,我都会在服务器挂起之前发送不同大小的图像。

Edit2:我忘了提到我在分区时尝试了不同大小的块,1024和500字节显示没有区别(921600中丢失了5-20个字节)。但我应该提一下,我正在发送并从localhost接收,这已经提供了最小的错误。

2 个答案:

答案 0 :(得分:1)

  

我知道UDP不可靠且难以使用,但我读到UDP在许多视频流应用程序中使用,所以我相信应该存在解决这个问题的方法,但我找不到它。

那些家伙可以。他们设计他们的协议,知道数据可能会丢失(甚至相反,多次到达),它可能无序到达,他们的协议/应用程序期望。

您不能简单地将数据剪切成碎片并使用UDP发送。您必须以每个消息各自具有意义的方式形成每个单独的消息。如果它是"流"它必须包含特定数据片段在流中的位置,当您的应用程序收到它时,它将知道是否可以处理给定的数据,它是否过时(到达太晚,或已经到达),它应该放在一边,并希望某些前面的部分可能会到达,或许它本身无法使用,应用程序应该向发送方发送直接请求,以便再次同步事物。

如果要传输图像 - 或一系列图像 - ,您可以发送数据的偏移量,并在收到内容时简单地将固定大小的缓冲区(可以托管一个整个图像)覆盖给定的偏移量,然后渲染结果。然后缓冲区将始终包含一些图像,至少是几个图像的混合 - 或者在非常幸运的情况下单个,"真实"图像。

编辑:评估'的一个例子。如何处理包:除了偏移之外,图像的数量('时间戳')也可以存在,然后应用程序可以避免用旧的东西覆盖图像的新部分 - 应该是过去的数据包(重新)出于任何原因。

答案 1 :(得分:0)

为什么使用最大缓冲区限制?您可以通过UDP可靠发送的最大有效负载是534字节。发送超过这个可能会导致碎片。如果您担心数据丢失,请使用TCP。