在python中发送/接收文件UDP

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13993514/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 10:07:36  来源:igfitidea点击:

sending/receiving file UDP in python

pythonsocketsudpfile-transfersender

提问by Hamoudaq

I've made this sending / receiving scripts but i corrupted file ! i have no idea why I'm getting this issue !

我已经制作了这个发送/接收脚本,但我损坏了文件!我不知道为什么我会遇到这个问题!

sender.py

发件人.py

#!/usr/bin/env python

from socket import *
import sys

s = socket(AF_INET,SOCK_DGRAM)
host =sys.argv[1]
port = 9999
buf =1024
addr = (host,port)

file_name=sys.argv[2]

f=open(file_name,"rb") 
data = f.read(buf)

s.sendto(file_name,addr)
s.sendto(data,addr)
while (data):
    if(s.sendto(data,addr)):
        print "sending ..."
        data = f.read(buf)
s.close()
f.close()

receiver.py

接收器.py

#!/usr/bin/env python

from socket import *
import sys
import select

host="0.0.0.0"
port = 9999
s = socket(AF_INET,SOCK_DGRAM)
s.bind((host,port))

addr = (host,port)
buf=1024

data,addr = s.recvfrom(buf)
print "Received File:",data.strip()
f = open(data.strip(),'wb')

data,addr = s.recvfrom(buf)
try:
    while(data):
        f.write(data)
        s.settimeout(2)
        data,addr = s.recvfrom(buf)
except timeout:
    f.close()
    s.close()
    print "File Downloaded"

and this the original receiver that I've modify it (works fine 100%)

这是我修改过的原始接收器(工作正常 100%)

#!/usr/bin/env python

from socket import *
import sys
import select

host="0.0.0.0"
port = 9999
s = socket(AF_INET,SOCK_DGRAM)
s.bind((host,port))

addr = (host,port)
buf=1024

f = open("file.pdf",'wb')

data,addr = s.recvfrom(buf)
try:
    while(data):
        f.write(data)
        s.settimeout(2)
        data,addr = s.recvfrom(buf)
except timeout:
    f.close()
    s.close()
    print "File Donwloaded"

as you notice it's making file at the beginning.

正如您注意到的那样,它在开始时正在制作文件。

exacted: client => send file (name.ext) => server:save it (name.ext)

精确:客户端=> 发送文件(名称.ext)=> 服务器:保存(名称.ext)

my output : corrupted file for pdf and empty for txt

我的输出:pdf 文件损坏,txt 文件为空

回答by Thomas Orozco

There are two problems here:

这里有两个问题:

Syntax errors:

语法错误:

You're using a from socket import *. It's not an error on its own, but it becomes one when you do except socket.timeout.

你正在使用一个from socket import *. 这本身不是一个错误,但当你这样做时它就会变成一个错误except socket.timeout

Using UDP:

使用UDP

Using UDP, corruption shouldn't be a surprise. You probably don't want to be using UDP here, you should switch to TCP.

使用 UDP,损坏不应该是一个意外。您可能不想在这里使用 UDP,您应该切换到 TCP。

Here's why UDP is not appropriate here:

这就是 UDP 在这里不合适的原因:

  • Packets may be lost but others could still reach their destination.
  • Packets may be duplicated
  • Packets may arrive in the wrong order
  • 数据包可能会丢失,但其他数据包仍可到达目的地。
  • 数据包可能重复
  • 数据包可能以错误的顺序到达

Note that switching to TCP will involve some refactoring of your code (it's a bit more complicated that just replacing SOCK_DGRAMwith SOCK_STREAM), but in your case, you have to do it.

请注意,切换到 TCP 将涉及对您的代码进行一些重构(仅替换SOCK_DGRAM为 会更复杂一些SOCK_STREAM),但在您的情况下,您必须这样做



I'm not saying UDP is bad, but it's not appropriate in your case.

我并不是说 UDP 不好,但它不适合您的情况。

回答by ATOzTOA

The problem with your code:

您的代码的问题:

  • When data is send through sockets, normally the lower layers will merge the data from multiple sendTo calls and send them together to reduce network load.
  • You are sending the first 1024 bytes of the file twice.
  • 当数据通过套接字发送时,通常低层会将来自多个 sendTo 调用的数据合并在一起发送,以减少网络负载。
  • 您要发送文件的前 1024 个字节两次。

What you should do:

你应该做什么:

Use some kind of a delimiter string having couple of characters (like "**_$$") so that it won't exist in the actual file binary representation. Then append this delimiter to the end of the filename.

使用某种具有几个字符的分隔符字符串(如“**_$$”),这样它就不会存在于实际的文件二进制表示中。然后将此分隔符附加到文件名的末尾。

Read from file again before starting the while loop.

在开始 while 循环之前再次从文件中读取。

At receiver end, receive everything into a single stream and then split using the delimiter. You will have the filename and the file data.

在接收器端,将所有内容接收到单个流中,然后使用分隔符进行拆分。您将拥有文件名和文件数据。

Update:

更新:

Working Code (Ubuntu / Windows XP)

工作代码 (Ubuntu / Windows XP)

# ----- sender.py ------

#!/usr/bin/env python

from socket import *
import sys

s = socket(AF_INET,SOCK_DGRAM)
host =sys.argv[1]
port = 9999
buf =1024
addr = (host,port)

file_name=sys.argv[2]

s.sendto(file_name,addr)

f=open(file_name,"rb")
data = f.read(buf)
while (data):
    if(s.sendto(data,addr)):
        print "sending ..."
        data = f.read(buf)
s.close()
f.close()


# ----- receiver.py -----

#!/usr/bin/env python

from socket import *
import sys
import select

host="0.0.0.0"
port = 9999
s = socket(AF_INET,SOCK_DGRAM)
s.bind((host,port))

addr = (host,port)
buf=1024

data,addr = s.recvfrom(buf)
print "Received File:",data.strip()
f = open(data.strip(),'wb')

data,addr = s.recvfrom(buf)
try:
    while(data):
        f.write(data)
        s.settimeout(2)
        data,addr = s.recvfrom(buf)
except timeout:
    f.close()
    s.close()
    print "File Downloaded"

Usage

用法

>> python recevier.py


>> python sender.py localhost filename.txt