用python发送/接收UDP文件

2024-06-11 03:44:29 发布

您现在位置:Python中文网/ 问答频道 /正文

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

发件人.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()

接收器.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"

正如你所注意到的,它正在开始制作文件。

严格要求: client=>;发送文件(name.ext)=>;服务器:保存文件(name.ext)

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


Tags: 文件nameimporthostclosedataportusr
2条回答

这里有两个问题:

语法错误:

你用的是from socket import *。这本身并不是一个错误,但当您这样做时,它就会变成一个错误。

使用UDP

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

以下是UDP在这里不适用的原因:

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

请注意,切换到TCP需要对代码进行一些重构(用SOCK_STREAM替换SOCK_DGRAM稍微复杂一点),但在您的情况下,您必须这样做。


我不是说UDP是坏的,但它不适合你的情况。

你的代码有问题:

  • 当数据通过套接字发送时,通常较低层将合并来自多个send to调用的数据并将它们一起发送,以减少网络负载。
  • 您将发送文件的前1024个字节两次。

你应该做什么:

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

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

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

更新:

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

相关问题 更多 >