0

我编写了一个小程序,通过 udp 套接字连接将文件从客户端发送到服务器.. 程序正常工作,但如果我传输的文件大于 8192 kb,则流停止并且我收到的文件已损坏.. 我怎样才能避免这种情况局限性?

服务器.py

host = ...
port = ...
filename = ...

buf = 2048
addr = (host, port)

UDPSock = socket(AF_INET, SOCK_DGRAM)
UDPSock.bind(addr)

f = open(filename, 'wb')

block,addr = UDPSock.recvfrom(buf)
while block:
    if(block == "!END"): # I put "!END" to interrupt the listener
        break
    f.write(block)
    block,addr = UDPSock.recvfrom(buf)

f.close()
UDPSock.close()

客户端.py

host = ...
port = ...
filename = ...

buf = 2048
addr = (host, port)

UDPSock = socket(AF_INET, SOCK_DGRAM)

f = open(filename, 'rb')

block = f.read(buf)
while block:
        UDPSock.sendto(block, addr)
        block = f.read(buf)

UDPSock.sendto("!END", addr)
f.close()
UDPSock.close()
4

6 回答 6

2

您必须在发送 t 之前将文件拆分为更小的块。8192 相当大,我认为通过 Internet 发送它可能会遇到麻烦,我会坚持使用 512 字节。还要记住,UDP 不是一个可靠的协议,即您的某些数据包可能根本不来。我建议使用 TCP 传输文件,它解决了您在使用 UDP 时必须自己解决的所有问题。

于 2010-09-26T11:39:03.353 回答
1

您达到的 8192 限制对应于 Windows 中套接字发送和接收缓冲区的大小。我很惊讶它完全适用于 1460 字节以上的文件,因为数据包在被放到网络上之前会被截断到那个或更小。您是否在同一主机内进行测试?

当您弄清楚这一点后,您将不得不处理出现故障的数据包,不止一次,或者根本不处理。你确定你必须使用UDP吗?这不适合外行。

于 2010-09-26T12:36:12.983 回答
1

您还没有解释为什么必须使用 UDP - 它根本不是为大量数据传输而设计的,因为它没有任何(简单的)拥塞管理。

如果您正在发送 VoIP,那么当不是简单地实时传输,而不是“尽可能快”时?

FWIW,典型的 VoIP 系统将数据打包成 20 毫秒左右的块。因此,如果您使用像 GSM 这样需要 13 kbps 的语音编解码器,您只需将每个数据包分成 260 位(约 32 字节),并每 0.02 秒发送一次。

于 2010-09-27T07:26:39.923 回答
1

使用 tcp 传输大文件可能是个好主意。

您需要对 udp 做的是将文件拆分成块,处理丢失的块,重试和乱序 pkts。

使用 tcp 你不会。

于 2010-09-26T11:46:53.433 回答
1

您所做的只是重新实现 TCP 非常糟糕,使用 UDP 的唯一原因应该是一对多传输或持续运行的企业服务总线中间件。

在用尽现有定义明确的传输之后,应将 UDP 用作不可靠的单向传输来考虑一个非常小的利基解决方案。

请注意,通过 Internet 进行的大数据传输,小写“I”仍然是唯一可靠的,您通常应该添加应用程序框架和有效负载验证。

我建议研究现有的文件传输技术,例如FSP (UDP)、HTTP (TCP)、SPDY(优化的 HTTP),或者与您自己在现有的面向消息的中间件系统(例如JBoss0MQ )之上滚动的其他通信集成。

于 2010-09-27T07:06:52.200 回答
1

如果您必须使用 UDP,请查看http://en.wikipedia.org/wiki/Trivial_File_Transfer_Protocol

它定义了一个可靠的协议。如果您的上下文允许 TCP,您应该更喜欢使用它。

于 2010-09-27T07:38:10.327 回答