在Python中发送/接收文件UDP



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

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]
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

#!/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"

这是我修改它的原始接收器(正常工作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"

您注意到它是在开始时制作文件的。

严格:客户端=>发送文件(name.ext)=>服务器:保存(name.ext)

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

您的代码问题:

  • 当数据通过插座发送时,通常下层将从多个sendto调用中合并数据并将其发送在一起以减少网络负载。
  • 您将两次发送文件的第一个1024字节。

您应该做什么:

使用具有几个字符(例如" ** _ $$")的某种定界符字符串,以便它在实际文件二进制表示中不存在。然后将此定界符附加到文件名的末尾。

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

在接收器端,将所有内容接收到一个流中,然后使用定界符分开。您将拥有文件名和文件数据。

更新:

工作代码(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"

用法

>> python recevier.py

>> python sender.py localhost filename.txt

这里有两个问题:

语法错误:

您正在使用from socket import *。这不是一个错误,但是当您进行except socket.timeout时,它会成为一个错误。

使用UDP:

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

这就是为什么UDP在这里不合适:

  • 数据包可能会丢失,但其他人仍然可以到达目的地。
  • 可以重复的数据包
  • 数据包可能到达错误的顺序

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

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

最新更新