问题
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