Python UDP 套接字丢包问题

1 投票
1 回答
1877 浏览
提问于 2025-04-18 04:56

我正在用UDP实现客户端和服务器之间的通信,这个协议是用来传输FTP的。首先,你不用告诉我UDP不可靠,我知道这一点。我的做法是:客户端请求一个文件,服务器就用带有序列号的UDP数据包向客户端发送数据,然后问“你漏掉了什么?”,再把那些漏掉的数据包重新发送。在本地网络中,数据包丢失率小于1%。我对套接字编程还比较陌生,所以对所有的套接字选项不太熟悉(网上大多数例子都是针对TCP的)。

我遇到的问题是我的客户端在接收这些数据时出现了问题。

PACKET_SIZE = 9216
mysocket.sendto('GO!', server_addr)
while True:
    resp = mysocket.recv(PACKET_SIZE)
    worker_thread.enqeue_packet(resp)

但是当数据回到.recv()时,已经漏掉了一些UDP数据包(我用wireshark确认这些数据包确实被发送了)。我可以通过让服务器稍微慢一点发送来解决这个问题(实际上,加入一些日志语句就足够造成延迟,让一切正常运作)。

我该如何确保socket.recv在处理一个数据包的过程中不会漏掉任何东西呢?我尝试把数据推送到一个单独的线程中,然后再放到一个队列里,但这仍然不够。

有没有什么好的主意?比如select、recv_into、setblocking?

1 个回答

1

你可能已经知道,UDP是不可靠的,但你可能没注意到TCP还有其他优点。对你来说,TCP有流量控制的功能,如果接收方跟不上发送方的速度(比如说丢包),TCP会自动降低发送速度。所以在正常的连接中,数据传输时应该优先选择TCP。对于延迟较高的连接(比如卫星链接),默认设置下TCP的表现就不太好了,因此有些人会设计自己的传输协议(大多数是用UDP),而另一些人则会调整现有的TCP设置。

我不知道你为什么使用UDP,但如果你想继续使用它,应该给发送方添加一种反馈通道,告诉它当前的丢包情况,这样它才能降低发送速度。也许你可以看看RTCP,它是和RTP一起使用的(RTP常用于语音通话等)。

撰写回答