【问题标题】:sending/receiving file UDP in python在python中发送/接收文件UDP
【发布时间】:2012-12-09 05:35:29
【问题描述】:

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

发件人.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 文件为空

【问题讨论】:

  • 首先:except socket.timeout: 永远不会起作用。你在做from socket import *,所以你的代码中的socket实际上是socket.socket。您应该使用except timeout 或使用import socket强烈推荐)。
  • 我得到了socket.timeout:超时,,,,当我发送pdf文件然后打开它时它说它是损坏的文件,我有关于UDP的基本知识我已经尝试过我的编码在问题中提供,谢谢
  • @ThomasOrozco 谢谢你,你已经修复了错误部分,但是如果我发送一个小文件,它不会停止(小于 1028),但是当我发送大文件时,我遇到了另一个问题工作正常,我正在考虑更改缓冲区大小

标签: python sockets udp file-transfer sender


【解决方案1】:

这里有两个问题:

语法错误:

您使用的是from socket import *。它本身并不是一个错误,但是当您执行except socket.timeout 时它就会变成一个错误。

使用UDP:

使用 UDP,不会出现损坏。您可能不想在这里使用 UDP,您应该切换到 TCP。

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

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

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


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

【讨论】:

  • 但是我有另一个脚本可以接收文件而不会损坏,但是该脚本的问题是它只是接收文件并用随机名称命名,我只是拿了它并修改它以接收名称和文件客户
  • @EngHamoud 如果您需要这方面的帮助,您需要提供更多信息(预期输出与实际输出)! :)
  • 如果我不得不猜测,我会说他必须做这样一个UDP文件传输程序的原因是因为一些学校作业来制作一个UDP文件传输程序...因为我能想到使用 UDP 进行文件传输的唯一原因是解释 TCP 的工作原理...因为要制作可靠的 UDP 文件传输程序,您需要处理丢失的数据包,并从乱序发送的数据包中重新组装文件a la bittorrent...您还需要在最后发送某种终结符,让接收者知道它已经完成。
【解决方案2】:

你的代码有问题:

  • 通过套接字发送数据时,通常下层会将来自多个 sendTo 调用的数据合并在一起发送,以减少网络负载。
  • 您将文件的前 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

【讨论】:

  • f.write(str[1]) IndexError: list index out of range
  • 错误的意思是,接收到的数据中没有分隔符。尝试发送一个文本文件并打印出收到的全部数据...
  • 用 pdf 试过,得到 TypeError: file() argument 1 must be encrypted string without NULL bytes, not str 用 txt 试过,得到 IndexError: list index out of range
  • windows,我觉得跟os没关系
  • 它在带有 Python 2.6 的 Ubuntu 中运行良好。请使用您尝试使用的最新代码和错误消息(包括行号)更新您的问题。
猜你喜欢
  • 1970-01-01
  • 2021-07-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-22
  • 1970-01-01
  • 2011-11-22
相关资源
最近更新 更多