sending/receiving file UDP in python

不羁岁月 提交于 2020-01-21 00:38:50

问题


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

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"

and this the original receiver that I've modify it (works fine 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)

my output : corrupted file for pdf and empty for txt


回答1:


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.

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.

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)

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



回答2:


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.

Using UDP:

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

Here's why UDP is not appropriate here:

  • 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_DGRAM with SOCK_STREAM), but in your case, you have to do it.


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



来源:https://stackoverflow.com/questions/13993514/sending-receiving-file-udp-in-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!