sending/receiving file UDP in python

Hamoudaq picture Hamoudaq · Dec 21, 2012 · Viewed 47.2k times · Source

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

Answer

Thomas Orozco picture Thomas Orozco · Dec 21, 2012

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.