如何避免UDP套接字传输限制?
我编写了一个小程序,通过 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()
I write a little program that sends file from client to server trough udp socket connection.. the program works correctly but if the file I transfer is larger than 8192 kb the stream stops and the file I receive is corrupt..
How can I avoid this limitation?
server.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()
client.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()
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
在发送 t 之前,您必须将文件分割成更小的块。 8192 相当大,我认为通过互联网发送它时可能会遇到麻烦,我会坚持使用 512 字节。另请记住,UDP 不是可靠的协议,即您的某些数据包可能根本不会到达。我建议使用TCP来传输文件,它解决了您在使用UDP时必须自己解决的所有麻烦。
You have to split the file into smaller chunks before sending t. 8192 is quite big and I think you could get in trouble when sending this over the Internet, I would stick to 512 bytes instead. Also remember that UDP is not a reliable protocol, i.e. some of your packets might not come at all. I suggest using TCP for transferring files, it solves all the trouble you will have to solve yourself when using UDP.
您仍然没有解释为什么必须使用 UDP - 它根本不是为大容量数据传输而设计的,因为它没有任何(简单的)拥塞管理。
如果您发送 VoIP,那么何时不只是实时传输,而不是“尽可能快”?
FWIW,典型的 VoIP 系统将数据打包成 20 毫秒左右的块。因此,如果您使用像 GSM 这样需要 13 kbps 的语音编解码器,则只需将每个数据包分成 260 位(约 32 字节),并每 0.02 秒发送一次。
You still haven't explained why you must use UDP - it simply isn't designed for high volume data transfers as it doesn't have any (simple) congestion management.
If you are sending VoIP then when not simply transmit at real-time, not "as fast as possible"?
FWIW, typical VoIP systems packetise the data into 20ms chunks or thereabouts. Hence if you're using an voice codec like GSM which requires 13 kbps, you only need to chunk into 260 bits (~32 bytes) per packet, and send them every 0.02 seconds.
使用 tcp 进行大文件传输可能是个好主意。
您需要对 udp 执行的操作是将文件拆分为块、处理丢失的块、重试和乱序 pkt。
对于 TCP,你不需要。
it would probably be a good idea to use tcp for large file transfers.
What you would need to do with udp is split the file up into chunks, hanle lost chunks, retrying and out of order pkts.
With tcp you dont.
您达到的 8192 限制对应于套接字发送和发送的大小。 Windows 中的接收缓冲区。我很惊讶它竟然适用于超过 1460 字节的文件,因为数据包在传输到网络之前会被截断为该大小或更小。您是否在同一主机内进行测试?
当您弄清楚这一点后,您将不得不多次处理无序产生的数据包,或者根本不处理。您确定必须使用 UDP 吗?这不适合外行。
The 8192 limit you hit corresponds to the size of socket send & receive buffers in Windows. I'm surprised it works at all for files above 1460 bytes, as the packets would have been truncated to that or smaller before they were put onto the wire. Were you testing within the same host?
When you've figured that out, you will then have to deal with packets ariving out of order,, more than once, or not at all. Are you sure you have to use UDP? It's not for the uninitiated.
您所做的只是非常糟糕地重新实现 TCP,使用 UDP 的唯一原因应该是用于一对多传输或持续运行的企业服务总线中间件。
在用尽现有的明确定义的传输之后,使用 UDP 作为不可靠的单向传输应该被视为一个非常小的利基解决方案。
请注意,对于通过互联网进行的大数据传输,小写的“I”仍然是可靠的,您通常应该添加应用程序框架和有效负载验证。
我建议研究现有的文件传输技术,例如 FSP (UDP)、HTTP (TCP),SPDY(优化的 HTTP),或者用于与在现有面向消息的中间件系统(例如 JBoss 或 0MQ。
All you are doing is very poorly re-implementing TCP, the only reason to use UDP should be for 1-to-many transfers or a constantly running enterprise service bus middleware.
Using UDP as an unreliable uni-directional transport should be considered a very small niche solution after exhausting the existing well defined transports.
Note for large data transfers over an internet, lower case 'I', are still only reliable and you should usually add application framing and payload verification.
I would recommend investigating existing file transfer technologies such as FSP (UDP), HTTP (TCP), SPDY (optimised HTTP), or for integration with other communications rolling your own above an existing message-orientated-middleware system such as JBoss or 0MQ.
如果您必须使用 UDP,请查看 http://en.wikipedia.org/wiki/Trivial_File_Transfer_Protocol
它定义了一个可靠的协议。如果您的上下文允许 TCP,您应该更喜欢使用它。
If you have to use UDP, look at http://en.wikipedia.org/wiki/Trivial_File_Transfer_Protocol
It defines a reliable protocol. If your context allows TCP you should prefer to use that.